Files
OmniRoute/tests/unit/standalone-server-ws-keepalive-timeout-7003.test.ts
Diego Rodrigues de Sa e Souza 83cca4d20f fix(build): packed tarball boot crash — server-ws timeout import escaped the package (#7065 class) (#7308)
* fix(build): server-ws timeout helper as shipped sibling — ../../src import crashed every packed boot (#7065 class)

* test(build): align pack-artifact-policy fixture with the new dist/main-server-timeouts.mjs required path
2026-07-15 20:05:53 -03:00

78 lines
3.9 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
// #7003 — the RED/GREEN spec in main-server-keepalive-timeout-7003.test.ts proves
// getMainServerTimeoutConfig() raises keepAliveTimeout/headersTimeout above Node's
// unconfigured 5_000ms default, and that the original fix wired it into
// scripts/dev/run-next.mjs. But run-next.mjs only runs `npm run dev`/`npm start`
// from a source checkout. The server real end users run — `omniroute serve`
// (npm-installed CLI), Docker, and Electron — spawns the standalone Next build's
// server.js via scripts/dev/run-standalone.mjs, which prefers server-ws.mjs
// (built from scripts/dev/standalone-server-ws.mjs, copied byte-for-byte into
// dist/server-ws.mjs by scripts/build/assembleStandalone.mjs) over the bare
// server.js specifically because it wraps `http.createServer` with production
// behavior the bare server lacks (peer-IP stamping, method/HEAD guards, WS
// proxying, TLS). Before this fix, that wrapper left Node's http.Server
// keepAliveTimeout/headersTimeout at their unconfigured defaults, so the
// JetBrains AI Assistant reconnect bug reproduced by main-server-keepalive-timeout
// -7003.test.ts still hit the production entry point every real user runs.
//
// standalone-server-ws.mjs has top-level side effects (monkeypatches
// http.createServer, generates a random UUID, and unconditionally
// `await import("./server.js")` — a file that only exists in the assembled
// standalone output, not in the source tree) so it cannot be imported
// in-process. Guard the fix by inspecting the source, mirroring the pattern
// used for run-next.mjs in run-next-node-env.test.ts.
const here = path.dirname(fileURLToPath(import.meta.url));
const source = fs.readFileSync(
path.resolve(here, "../../scripts/dev/standalone-server-ws.mjs"),
"utf8"
);
test("standalone-server-ws.mjs imports getMainServerTimeoutConfig", () => {
// The wrapper must import the SIBLING ./main-server-timeouts.mjs — a
// ../../src/... import escapes the package after the dist-root copy and
// crashed every packed boot (2026-07-15, #7065 class). Parity with the
// canonical runtimeTimeouts.ts is guarded by main-server-timeouts-parity.test.ts.
assert.match(
source,
/import\s*\{\s*getMainServerTimeoutConfig\s*\}\s*from\s*["']\.\/main-server-timeouts\.mjs["']/,
"expected the production server wrapper to import getMainServerTimeoutConfig " +
"from its shipped sibling module (./main-server-timeouts.mjs)"
);
});
test("standalone-server-ws.mjs applies keepAliveTimeout/headersTimeout to the wrapped server", () => {
assert.match(
source,
/server\.keepAliveTimeout\s*=\s*\w*[Tt]imeouts?\.keepAliveTimeoutMs/,
"expected the wrapped server object to have keepAliveTimeout set from getMainServerTimeoutConfig()"
);
assert.match(
source,
/server\.headersTimeout\s*=\s*\w*[Tt]imeouts?\.headersTimeoutMs/,
"expected the wrapped server object to have headersTimeout set from getMainServerTimeoutConfig()"
);
});
test("keepAliveTimeout/headersTimeout are applied inside createServerWithResponsesWs, before the server is returned", () => {
const factoryIdx = source.search(/function createServerWithResponsesWs/);
const keepAliveIdx = source.search(/server\.keepAliveTimeout\s*=/);
const returnIdx = source.search(/return server;/);
assert.ok(factoryIdx !== -1, "expected createServerWithResponsesWs to exist");
assert.ok(keepAliveIdx !== -1, "expected a server.keepAliveTimeout assignment to exist");
assert.ok(returnIdx !== -1, "expected the wrapped server to be returned");
assert.ok(
keepAliveIdx > factoryIdx,
"timeout wiring must happen inside createServerWithResponsesWs"
);
assert.ok(
keepAliveIdx < returnIdx,
"timeout wiring must happen before the server object is returned to the caller"
);
});