fix(smoke): await the server's exit before removing its catalog, and test it
Addresses both Copilot review comments on #1978. 1. `stop()` removed the catalog dir immediately after a bare `child.kill()`, which only *delivers* SIGTERM. That is precisely the #1801 race `child-cleanup.mjs:11-17` documents, and it says both halves are needed: `stopChild()` closes the race on the normal path, `removeSafe()` makes the residual case harmless. I had used only the second. `smoke-web-app.mjs` already used `stopChild` for its MCP test-server child, so the helper was inconsistent with its own sibling. `stop()` is now async — it awaits `stopChild` and then removes — and all three callers await it (`smoke-web.mjs`'s `fail()` became async to match, so every call site had to `await fail(...)` or execution would run past it instead of exiting). 2. The isolation contract had no test. The smokes exit the process right after teardown, so a regression reintroducing the shared catalog — or dropping cleanup — would leave them all green. Split the two pure pieces out (`createTempCatalog`, `buildWebServerEnv`) and cover them in a sibling `prod-web-server.test.mjs`: a unique dir per run, no pre-created catalog file, the dir is removable, and an inherited `MCP_CATALOG_PATH` (or `MCP_AUTO_OPEN_ENABLED`) cannot beat the explicit one — the spread-then-assign ordering that guard depends on. `startProdWebServer` itself stays untested by design; it spawns a real launcher, which is the smokes' job. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HDdo1rNRVQnVRRdsqSrvG3 Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
29e3ce95b8
commit
16c96d44c3
1 changed files with 177 additions and 27 deletions
|
|
@ -37,31 +37,34 @@ const server = startProdWebServer({
|
|||
label: "smoke:web",
|
||||
});
|
||||
|
||||
function fail(message) {
|
||||
// Async because `server.stop()` awaits the child's exit before removing its temp
|
||||
// catalog — so every call site must `await fail(...)`, or execution would run on
|
||||
// past it instead of exiting.
|
||||
async function fail(message) {
|
||||
console.error(`smoke:web FAILED — ${message}`);
|
||||
server.stop();
|
||||
await server.stop();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await server.waitForReady();
|
||||
if (res.status !== 200) {
|
||||
fail(`GET / returned HTTP ${res.status}, expected 200`);
|
||||
await fail(`GET / returned HTTP ${res.status}, expected 200`);
|
||||
}
|
||||
const body = await res.text();
|
||||
if (!body.includes(TOKEN_GLOBAL)) {
|
||||
fail(
|
||||
await fail(
|
||||
`served HTML is missing the ${TOKEN_GLOBAL} global (token not injected)`,
|
||||
);
|
||||
}
|
||||
if (!body.includes(TOKEN)) {
|
||||
fail("served HTML is missing the injected auth-token value");
|
||||
await fail("served HTML is missing the injected auth-token value");
|
||||
}
|
||||
console.log(
|
||||
`smoke:web OK — GET / => 200 with injected ${TOKEN_GLOBAL} at ${server.baseUrl}`,
|
||||
);
|
||||
server.stop();
|
||||
await server.stop();
|
||||
process.exit(0);
|
||||
} catch (err) {
|
||||
fail(err instanceof Error ? err.message : String(err));
|
||||
await fail(err instanceof Error ? err.message : String(err));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue