/** * @file Tests for server/lib/lane-gc.js's capOversizedLogs — pure fs, safe to * test directly. reapOrphanMcp shells out to pgrep/ps against real OS * processes; no automated test for that here (same reasoning routes with no * HTTP test harness already use in this repo) — verified via manual smoke * check per the F3c design spec. * @author Nguyễn Ngọc Trí Vĩ */ const { describe, it, after } = require("node:test"); const assert = require("node:assert/strict"); const fs = require("node:fs"); const os = require("node:os"); const path = require("node:path"); // LANES_ROOT is read once at require time (from worktree.js) — set it before // the first require, then use it as a fixed root every test writes under. const SUITE_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), "ccam-gc-")); process.env.LANES_ROOT = SUITE_ROOT; const laneGc = require("../lib/lane-gc"); after(() => fs.rmSync(SUITE_ROOT, { recursive: true, force: true })); function writeLog(laneSlot, name, sizeBytes, fill = "x") { const dir = path.join(SUITE_ROOT, ".state", `lane${laneSlot}`, "logs"); fs.mkdirSync(dir, { recursive: true }); const filePath = path.join(dir, name); fs.writeFileSync(filePath, fill.repeat(sizeBytes)); return filePath; } describe("capOversizedLogs", () => { it("leaves a log under the 10MB cap untouched", () => { const filePath = writeLog(1, "boot.log", 1024); const before = laneGc.capOversizedLogs(); assert.deepEqual( before.filter((c) => c.path === filePath), [] ); assert.equal(fs.statSync(filePath).size, 1024); }); it("caps a log over 10MB to its last 2MB, in place", () => { const dir = path.join(SUITE_ROOT, ".state", "lane2", "logs"); fs.mkdirSync(dir, { recursive: true }); const filePath = path.join(dir, "e2e.log"); const fd = fs.openSync(filePath, "w"); // Distinguishable content: 9MB of 'a', then a 2MB tail of 'b's we can // assert survived, sized to land over the 10MB cap. fs.writeSync(fd, "a".repeat(9 * 1024 * 1024)); fs.writeSync(fd, "b".repeat(2 * 1024 * 1024)); fs.closeSync(fd); const result = laneGc.capOversizedLogs(); const entry = result.find((c) => c.path === filePath); assert.ok(entry, "expected e2e.log to be reported as capped"); assert.equal(entry.sizeBefore, 11 * 1024 * 1024); const capped = fs.readFileSync(filePath, "utf8"); assert.equal(capped.length, 2 * 1024 * 1024); assert.ok(capped.split("").every((ch) => ch === "b")); }); it("--dry-run reports what would be capped without touching the file", () => { const filePath = writeLog(3, "boot.log", 11 * 1024 * 1024); const result = laneGc.capOversizedLogs({ dryRun: true }); const entry = result.find((c) => c.path === filePath); assert.ok(entry, "expected boot.log to be reported as would-be-capped"); assert.equal(fs.statSync(filePath).size, 11 * 1024 * 1024); }); });