testBuildsWaitForASlot
A build of an app takes a slot of the machine's, as tests do: with the one slot held by other work (another
branch's verify), tcm build waits, saying on whom, and builds once it's given back, leaving the slots as they were.
import { plainEnv, strip, tcmBin, tempDir, withChildren } from "#codebase/tcmts/cli/test/e2e/harness"; import { setUp } from "#codebase/tcmts/cli/test/e2e/prod"; import assert from "node:assert/strict"; import { spawn } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; export const testBuildsWaitForASlot = () => withChildren(async (keep) => { const { dir, tcm, scratch } = setUp(); scratch(`// tcm: namespace app export async function main() { document.querySelector("#app")!.textContent = "hello"; } `); tcm("add"); const slots = tempDir("slots for a build"); // (held by this test's process, which is alive, as another tcm's verify would hold it) fs.writeFileSync( path.join(slots, "slot-0"), JSON.stringify({ pid: process.pid, what: "verify of /x/codebase on session/other", since: Date.now(), token: "t", }), ); // (out of the suite's own slot, which what a suite runs is otherwise in) const { TCM_SUITE_SLOT: _, ...outer } = plainEnv(); const child = keep( spawn(process.execPath, [tcmBin(), "build", "app.main"], { cwd: dir, env: { ...outer, TCM_SLOTS: "1", TCM_SLOTS_DIR: slots }, }), ); let out = ""; child.stdout!.setEncoding("utf8").on("data", (d: string) => (out += d)); child.stderr!.setEncoding("utf8").on("data", (d: string) => (out += d)); const ended = new Promise<number | null>((r) => child.on("close", r)); for (let i = 0; i < 300 && !/waiting for a slot/.test(out); i++) await new Promise((r) => setTimeout(r, 100)); assert.match( strip(out), /waiting for a slot: 1 of 1 in use \(1 by session\/other's verify of …\/x\/codebase\) \(TCM_SLOTS sets how many\)\n/, ); await new Promise((r) => setTimeout(r, 500)); assert.equal(child.exitCode, null, "still waiting"); assert.doesNotMatch(out, /built/); fs.rmSync(path.join(slots, "slot-0")); assert.equal(await ended, 0, out); assert.match(strip(out), /got a slot after [\d.]+s\n/); assert.match(strip(out), /built app\.main/); assert.deepEqual(fs.readdirSync(slots), []); })