Files
fusion/scripts/__tests__/boot-smoke.test.mjs
gsxdsm 6d2c1bf0c9 FN-9020: parallelize boot smoke preflights
Reduce durable boot-smoke latency while preserving its CLI, initialization, health, and shutdown assertions.

- Run independent help and init preflights concurrently with bounded async child processes.
- Add phase timing diagnostics and deterministic init failure classification.
- Cover phase scheduling and isolated environment behavior, and document the diagnostics flag.

Files changed:
 docs/testing.md                       |   4 +-
 scripts/__tests__/boot-smoke.test.mjs |  65 ++++++++++-
 scripts/boot-smoke.mjs                | 201 +++++++++++++++++++++++++---------
 3 files changed, 214 insertions(+), 56 deletions(-)

Fusion-Task-Id: FN-9020

Fusion-Task-Lineage: 1f5d3d7f-dc0c-4d16-a4ab-fd5e3952dbdf

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-12 19:45:40 -07:00

141 lines
5.2 KiB
JavaScript

// FNXC:BootSmoke 2026-07-07-00:00: Regression for the macOS ENOTEMPTY temp-dir
// cleanup race (FN-7662). Drives an injected `rm` to throw ENOTEMPTY and
// asserts `removeTempDir` tolerates it (retries/succeeds, or swallows a
// persistently-throwing remover) so a post-PASS cleanup can never fail the gate.
import test from "node:test";
import assert from "node:assert/strict";
import {
classifyInitFailure,
createBootSmokePhasePlan,
createChildEnv,
runPreflightPhasePlan,
removeTempDir,
} from "../boot-smoke.mjs";
function enotempty() {
const err = new Error("ENOTEMPTY: directory not empty");
err.code = "ENOTEMPTY";
return err;
}
test("removeTempDir tolerates ENOTEMPTY on the first call then succeeds", () => {
let calls = 0;
const rm = (dir, opts) => {
calls += 1;
assert.equal(dir, "/tmp/fusion-boot-smoke-home-xyz");
assert.equal(opts.recursive, true);
assert.equal(opts.force, true);
if (calls === 1) throw enotempty();
// second call (simulating rmSync's own internal retry succeeding): no throw
};
assert.doesNotThrow(() => {
removeTempDir("/tmp/fusion-boot-smoke-home-xyz", { rm });
});
assert.equal(calls, 1);
});
test("removeTempDir never throws even when rm always fails with ENOTEMPTY", () => {
let calls = 0;
const rm = () => {
calls += 1;
throw enotempty();
};
assert.doesNotThrow(() => {
removeTempDir("/tmp/fusion-boot-smoke-project-abc", { rm });
});
assert.equal(calls, 1);
});
test("removeTempDir calls rm with recursive/force and a positive maxRetries", () => {
let seenOpts;
const rm = (dir, opts) => {
seenOpts = opts;
};
removeTempDir("/tmp/fusion-boot-smoke-home-happy", { rm });
assert.equal(seenOpts.recursive, true);
assert.equal(seenOpts.force, true);
assert.ok(seenOpts.maxRetries > 0, "maxRetries should be positive");
assert.ok(typeof seenOpts.retryDelay === "number");
});
test("removeTempDir uses the provided maxRetries/retryDelayMs overrides", () => {
let seenOpts;
const rm = (dir, opts) => {
seenOpts = opts;
};
removeTempDir("/tmp/fusion-boot-smoke-project-custom", { rm, maxRetries: 9, retryDelayMs: 250 });
assert.equal(seenOpts.maxRetries, 9);
assert.equal(seenOpts.retryDelay, 250);
});
test("boot plan overlaps independent preflight checks while retaining all smoke assertions", () => {
for (const dataDir of ["cold", "warm"]) {
const plan = createBootSmokePhasePlan({ attempt: 2, dataDir });
assert.deepEqual(plan.map((phase) => phase.name), ["help", "init", "serve", "shutdown"]);
assert.deepEqual(plan.map((phase) => phase.assertion), [
"help-exits-0-and-mentions-serve",
"init-settles-and-writes-project-marker",
"health-200",
"sigterm-delivered-and-clean-exit",
]);
assert.equal(plan.filter((phase) => phase.concurrency === "preflight").length, 2);
assert.equal(plan.find((phase) => phase.name === "serve").attempt, 2);
assert.deepEqual(plan.find((phase) => phase.name === "serve").dependsOn, ["init"]);
assert.equal(plan.find((phase) => phase.name === "init").dataDir, dataDir);
}
});
test("production preflight scheduler launches independent phases before either settles", async () => {
const plan = createBootSmokePhasePlan();
const started = [];
const results = await runPreflightPhasePlan(plan, async (phase) => {
started.push(phase.name);
await new Promise((resolve, reject) => {
Promise.resolve().then(() => {
if (started.length !== 2) {
reject(new Error("preflight phase was awaited before every independent phase launched"));
return;
}
resolve();
});
});
return `${phase.name}-result`;
});
assert.deepEqual(started, ["help", "init"]);
assert.deepEqual(results, { help: "help-result", init: "init-result" });
});
test("init liveness classification preserves every failing state", () => {
const base = { error: null, status: 0, stdout: "", stderr: "" };
assert.equal(classifyInitFailure(base, true), null);
assert.equal(classifyInitFailure({ ...base, status: 13 }, true), "non-zero-exit");
assert.equal(classifyInitFailure({ ...base, stderr: "Detected unsettled top-level await" }, true), "unsettled-top-level-await");
assert.equal(classifyInitFailure(base, false), "missing-project-marker");
assert.equal(classifyInitFailure({ ...base, error: new Error("spawn failed") }, true), "process-error");
});
test("isolated child env strips inherited database and port controls", () => {
const env = createChildEnv({ DATABASE_URL: "postgres://ambient", FUSION_NO_EMBEDDED_PG: "1", PORT: "4040", KEEP: "yes" }, "/tmp/fusion-home");
assert.equal(env.HOME, "/tmp/fusion-home");
assert.equal(env.FUSION_SKIP_ONBOARDING, "1");
assert.equal(env.DATABASE_URL, undefined);
assert.equal(env.FUSION_NO_EMBEDDED_PG, undefined);
assert.equal(env.PORT, undefined);
assert.equal(env.KEEP, "yes");
});
test("importing boot-smoke.mjs does not boot a server (main() guard holds)", async () => {
// The module was already imported at the top of this file for `removeTempDir`.
// If the main()/bootAndVerify() top-level invocation ran unguarded, this test
// file would hang waiting on a spawned `fn serve` child. Reaching this
// assertion at all proves the import completed without side effects.
assert.ok(true);
});