test(testkit): cover the env-driven E2E ports instead of a fixed list
The ports test parsed a hard-coded array that no longer exists. It now runs the script on a fake host whose fuser finds nothing, and checks the default ports, the per-runner override, the rejection of a non-numeric setting, and that the workflow picks the ports before freeing them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
This commit is contained in:
parent
2f05ab6a81
commit
cd0aedafcd
@ -1,9 +1,12 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { chmodSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const repoRoot = path.resolve(import.meta.dirname, "../../..");
|
||||
const scriptPath = path.join(repoRoot, "scripts/free-e2e-ports.sh");
|
||||
const script = readFileSync(scriptPath, "utf8");
|
||||
const playwrightWorkflow = readFileSync(
|
||||
path.join(repoRoot, ".github/workflows/playwright.yml"),
|
||||
"utf8",
|
||||
@ -15,20 +18,62 @@ function portsFromShellArray(source: string, name: string): number[] {
|
||||
return [...match![1].matchAll(/\b(\d+)\b/g)].map(([, port]) => Number(port));
|
||||
}
|
||||
|
||||
/** Runs the script on a fake Linux host whose fuser never finds a listener, so nothing is killed. */
|
||||
function runScript(env: Record<string, string>): { status: number; output: string } {
|
||||
const fakeBin = mkdtempSync(path.join(tmpdir(), "evoo-e2e-ports-"));
|
||||
for (const [name, body] of [
|
||||
["uname", "echo Linux"],
|
||||
["fuser", "exit 1"],
|
||||
] as const) {
|
||||
const file = path.join(fakeBin, name);
|
||||
writeFileSync(file, `#!/usr/bin/env bash\n${body}\n`);
|
||||
chmodSync(file, 0o755);
|
||||
}
|
||||
try {
|
||||
const output = execFileSync("bash", [scriptPath], {
|
||||
env: { PATH: `${fakeBin}:${process.env.PATH}`, ...env },
|
||||
encoding: "utf8",
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
return { status: 0, output };
|
||||
} catch (error) {
|
||||
const failure = error as { status: number; stdout: string; stderr: string };
|
||||
return { status: failure.status, output: `${failure.stdout}${failure.stderr}` };
|
||||
}
|
||||
}
|
||||
|
||||
function announcedPorts(output: string): number[] {
|
||||
const match = output.match(/E2E ports \(([^)]*)\)/);
|
||||
expect(match, "announced E2E ports").toBeTruthy();
|
||||
return match![1].split(" ").map(Number);
|
||||
}
|
||||
|
||||
describe("free-e2e-ports.sh", () => {
|
||||
const script = readFileSync(scriptPath, "utf8");
|
||||
|
||||
it("declares dedicated E2E ports separate from live dev ports", () => {
|
||||
it("keeps the live dev ports apart from the default E2E ports", () => {
|
||||
const livePorts = portsFromShellArray(script, "LIVE_PORTS");
|
||||
const e2ePorts = portsFromShellArray(script, "E2E_PORTS");
|
||||
|
||||
expect(livePorts).toEqual([3100, 5173]);
|
||||
|
||||
const run = runScript({});
|
||||
expect(run.status).toBe(0);
|
||||
const e2ePorts = announcedPorts(run.output);
|
||||
expect(e2ePorts).toEqual([3110, 3111, 5180, 4321]);
|
||||
for (const livePort of livePorts) {
|
||||
expect(e2ePorts).not.toContain(livePort);
|
||||
}
|
||||
});
|
||||
|
||||
it("follows the harness port settings so runners on one host never touch each other", () => {
|
||||
const run = runScript({ API_PORT: "3310", WEB_PORT: "5380", WWW_PORT: "4521" });
|
||||
expect(run.status).toBe(0);
|
||||
expect(announcedPorts(run.output)).toEqual([3310, 3311, 5380, 4521]);
|
||||
});
|
||||
|
||||
it("refuses a port setting that is not a number", () => {
|
||||
const run = runScript({ API_PORT: "abc" });
|
||||
expect(run.status).toBe(1);
|
||||
expect(run.output).toContain("API_PORT must be a port number");
|
||||
});
|
||||
|
||||
it("uses fuser and skips non-Linux hosts", () => {
|
||||
expect(script).toContain('fuser -k "$spec"');
|
||||
expect(script).toContain('uname -s)" != "Linux"');
|
||||
@ -44,4 +89,13 @@ describe("free-e2e-ports.sh", () => {
|
||||
playwrightWorkflow.indexOf("Run marketing homepage E2E"),
|
||||
);
|
||||
});
|
||||
|
||||
it("gets its ports from the workflow step that picks them per runner", () => {
|
||||
const pickStep = playwrightWorkflow.indexOf("Pick E2E ports for this runner");
|
||||
expect(pickStep).toBeGreaterThan(-1);
|
||||
expect(pickStep).toBeLessThan(playwrightWorkflow.indexOf("free-e2e-ports.sh"));
|
||||
for (const setting of ["API_PORT=", "WEB_PORT=", "WWW_PORT="]) {
|
||||
expect(playwrightWorkflow).toContain(setting);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user