import assert from "node:assert/strict"; import { spawn } from "node:child_process"; import { copyFile, mkdir, mkdtemp, readFile, rm, writeFile, } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { test } from "node:test"; test("local runner orders builds, overlaps isolated files and propagates failures", async (t) => { const directory = await mkdtemp(join(tmpdir(), "flarebot-test-runner-")); t.after(() => rm(directory, { recursive: true, force: true })); await mkdir(join(directory, "scripts")); await mkdir(join(directory, "tests")); await copyFile("scripts/test.mjs", join(directory, "scripts/test.mjs")); await writeFile( join(directory, "package.json"), JSON.stringify({ type: "module", scripts: { typecheck: 'node --eval "process.exit(0)"', "build:release": "node build.mjs release", "build:control-plane:fixture": "node build.mjs publisher", }, }), ); await writeFile( join(directory, "build.mjs"), `import { appendFileSync, readFileSync } from "node:fs"; import assert from "node:assert/strict"; const phase = process.argv[2]; if (phase === "publisher") assert.equal(readFileSync("order", "utf8"), "release\\ncatalog\\n"); appendFileSync("order", phase + "\\n");`, ); await writeFile( join(directory, "tests/catalog.test.mjs"), `import { appendFileSync, readFileSync } from "node:fs"; import assert from "node:assert/strict"; assert.equal(readFileSync("order", "utf8"), "release\\n"); appendFileSync("order", "catalog\\n");`, ); await writeFile( join(directory, "tests/ownership.test.mjs"), `import { appendFileSync, readFileSync } from "node:fs"; import assert from "node:assert/strict"; assert.equal(readFileSync("order", "utf8"), "release\\ncatalog\\npublisher\\n"); appendFileSync("order", "ownership\\n");`, ); await writeFile( join(directory, "tests/discovered.test.mjs"), `import { existsSync, readFileSync } from "node:fs"; import { setTimeout } from "node:timers/promises"; import assert from "node:assert/strict"; assert.equal(readFileSync("order", "utf8"), "release\\ncatalog\\npublisher\\nownership\\n"); const deadline = Date.now() + 5000; while (!existsSync("peer-ready") && Date.now() < deadline) await setTimeout(10); assert.ok(existsSync("peer-ready"), "another file must run while this file waits"); assert.fail("discovered failure sentinel");`, ); await writeFile( join(directory, "tests/peer.test.mjs"), `import { writeFileSync } from "node:fs"; writeFileSync("peer-ready", "");`, ); const result = await new Promise((resolve, reject) => { // Start a fresh runner, rather than inheriting node:test's child marker. const env = { ...process.env, FLAREBOT_TEST_CONCURRENCY: "2" }; delete env.NODE_TEST_CONTEXT; const child = spawn(process.execPath, ["scripts/test.mjs", "--full"], { cwd: directory, env, stdio: ["ignore", "pipe", "pipe"], }); let output = ""; child.stdout.on("data", (data) => (output += data)); child.stderr.on("data", (data) => (output += data)); child.once("error", reject); child.once("close", (code) => resolve({ code, output })); }); assert.equal(result.code, 1, result.output); assert.match(result.output, /discovered failure sentinel/); assert.equal( await readFile(join(directory, "order"), "utf8"), "release\ncatalog\npublisher\nownership\n", ); });