testBranchVerifiesDontWaitForEachOther
tcmts.cli.test.e2e.verify.testBranchVerifiesDontWaitForEachOther · #5jgb4dce · term
import { Codebase } from "#codebase/tcmts/cli/codebase";
import { fakeVerify } from "#codebase/tcmts/cli/test/e2e/verify";
import { nodeArgs, writeRunner } from "#codebase/tcmts/loader";
import assert from "node:assert/strict";
import { spawn } from "node:child_process";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
export const testBranchVerifiesDontWaitForEachOther = async () => {
const dist = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), "tcm dist ")));
const log = path.join(dist, "log");
// something else making its tcm the known-good one, as a verify of before did for its whole run
const other = spawn(process.execPath, ["-e", "setInterval(() => {}, 1000)"], { stdio: "ignore" });
fs.writeFileSync(path.join(dist, "verify.lock"), String(other.pid));
const cb = Codebase.find(process.cwd());
const hash = (fakeVerify as unknown as Record<symbol, string>)[Symbol.for("tcm.hash")]!;
const runner = writeRunner(hash, cb.source(), cb.lay);
const ended = new Map<string, number>();
const start = (branch: string, name = branch) => {
const c = spawn(process.execPath, [...nodeArgs(cb.lay), runner, dist, branch, "1500", log], {
cwd: cb.lay.root,
stdio: ["ignore", "ignore", "pipe"],
});
let err = "";
c.stderr.setEncoding("utf8").on("data", (d: string) => (err += d));
return new Promise<void>((resolve, reject) =>
c.on("close", (code) => {
ended.set(name, Date.now());
if (code === 0) resolve();
else reject(new Error(`${name} exited ${code}: ${err}`));
}),
);
};
const lines = () =>
(fs.existsSync(log) ? fs.readFileSync(log, "utf8") : "")
.trim()
.split("\n")
.filter(Boolean)
.map((l) => l.split(" ") as [string, string, string]);
const at = (branch: string, what: string, nth = 0) =>
Number(lines().filter(([, b, w]) => b === branch && w === what)[nth]?.[0] ?? NaN);
try {
const runs = [
start("session/a"),
start("session/b"),
start("main"),
start("session/a", "session/a again"),
];
while (lines().filter(([, , w]) => w === "ready").length < 4)
await new Promise((r) => setTimeout(r, 50));
fs.writeFileSync(`${log}.go`, "");
await Promise.all(runs.slice(0, 2));
// the two branches built side by side, and beside main's
assert.ok(at("session/a", "build") < at("session/b", "built"));
assert.ok(at("session/b", "build") < at("session/a", "built"));
assert.ok(at("main", "build") < at("session/a", "built"));
// each in its own place
assert.deepEqual(fs.readdirSync(path.join(dist, "candidates")).sort().length, 3);
// another verify of the same branch waits for the first
await runs[3];
assert.ok(at("session/a", "build", 1) >= at("session/a", "built", 0));
// main's waits only to make its tcm the known-good one, for what else is
await new Promise((r) => setTimeout(r, 300));
assert.ok(
Number.isNaN(at("main", "promote")),
"main's verify promoted while another held dist/verify.lock",
);
other.kill("SIGKILL");
await runs[2];
assert.ok(at("main", "promote") >= at("main", "built"));
} finally {
other.kill("SIGKILL");
fs.rmSync(dist, { recursive: true, force: true });
}
}
uses