mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-14 13:22:37 +00:00
Keep subprocess regression tests independent of terminal colors (#6648)
* test(server): isolate subprocess regressions from terminal colors Inherited NO_COLOR and FORCE_COLOR make Node emit an unrelated warning. It contaminates argv-fixture stderr and fails the closed-output supervisor fixture before its pipe handlers are installed. Clear both settings only in these fixture subprocesses, preserving their output and lifecycle assertions. * test(server): exercise conflicting colors regardless of parent environment Run the closed-output and spaced-executable regressions with explicit conflicting color inputs as well as the inherited environment, so removing fixture isolation fails on ordinary CI environments too. --------- Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
@@ -29,6 +29,7 @@ async function runSupervisorFixture(options: {
|
||||
blockLogPath?: boolean;
|
||||
/** Close the reading end of the supervisor's stdout and stderr as soon as it starts. */
|
||||
closeOutput?: boolean;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): Promise<{
|
||||
code: number | null;
|
||||
signal: NodeJS.Signals | null;
|
||||
@@ -84,7 +85,9 @@ async function runSupervisorFixture(options: {
|
||||
];
|
||||
const child = spawn(command, args, {
|
||||
cwd: repoRoot,
|
||||
env: { ...process.env },
|
||||
// A Node color-conflict warning can hit closed stderr before runSupervisor installs
|
||||
// its pipe-error handlers. This fixture exercises the supervisor's own output.
|
||||
env: { ...process.env, ...options.env, NO_COLOR: undefined, FORCE_COLOR: undefined },
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
|
||||
@@ -205,10 +208,16 @@ describe("supervisor durable logging", () => {
|
||||
expect(result.stderr).toContain('"worker-json-stderr"');
|
||||
});
|
||||
|
||||
test("keeps supervising the worker when nobody reads its stdout or stderr", async () => {
|
||||
const result = await runSupervisorFixture({
|
||||
closeOutput: true,
|
||||
workerSource: `
|
||||
test.each([
|
||||
{ colors: "inherited", env: {} },
|
||||
{ colors: "conflicting", env: { NO_COLOR: "1", FORCE_COLOR: "1" } },
|
||||
])(
|
||||
"keeps supervising the worker when nobody reads its stdout or stderr with $colors colors",
|
||||
async ({ env }) => {
|
||||
const result = await runSupervisorFixture({
|
||||
closeOutput: true,
|
||||
env,
|
||||
workerSource: `
|
||||
process.on("message", (message) => {
|
||||
if (message?.type === "paseo:graceful-shutdown") process.exit(0);
|
||||
});
|
||||
@@ -220,14 +229,15 @@ describe("supervisor durable logging", () => {
|
||||
}, 500);
|
||||
setInterval(() => {}, 1000);
|
||||
`,
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.code).toBe(0);
|
||||
expect(result.signal).toBeNull();
|
||||
expect(result.log).toContain("first stderr line\n");
|
||||
expect(result.log).toContain("later stdout line\n");
|
||||
expect(result.log).toContain('"reason":"closed_output_probe"');
|
||||
});
|
||||
expect(result.code).toBe(0);
|
||||
expect(result.signal).toBeNull();
|
||||
expect(result.log).toContain("first stderr line\n");
|
||||
expect(result.log).toContain("later stdout line\n");
|
||||
expect(result.log).toContain('"reason":"closed_output_probe"');
|
||||
},
|
||||
);
|
||||
|
||||
test("preserves raw non-JSON stdout and stderr lines", async () => {
|
||||
const result = await runSupervisorFixture({
|
||||
|
||||
@@ -126,10 +126,15 @@ async function runFixture(params: {
|
||||
command: string;
|
||||
args: string[];
|
||||
shell?: boolean;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): Promise<SpawnResult> {
|
||||
const child = spawnProcess(params.command, params.args, {
|
||||
env: {
|
||||
...process.env,
|
||||
...params.env,
|
||||
// Terminal color settings must not add Node warnings to the argv fixture's stderr.
|
||||
NO_COLOR: undefined,
|
||||
FORCE_COLOR: undefined,
|
||||
PASEO_EXPECTED_ARGV_JSON: JSON.stringify(["--config", JSON_ARG]),
|
||||
},
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
@@ -216,6 +221,8 @@ async function findAndLaunch(fixture: LaunchFixture): Promise<{
|
||||
const child = spawnProcess(found, fixture.args, {
|
||||
env: {
|
||||
...process.env,
|
||||
NO_COLOR: undefined,
|
||||
FORCE_COLOR: undefined,
|
||||
PASEO_EXPECTED_ARGV_JSON: fixture.expectedArgvJson,
|
||||
PASEO_ARGV_SLICE_FROM: String(fixture.sliceFrom),
|
||||
},
|
||||
@@ -331,18 +338,25 @@ describe.runIf(isPlatform("win32"))("Windows spawn launch regression", () => {
|
||||
});
|
||||
|
||||
describe.skipIf(isPlatform("win32"))("spawn launch regression smoke", () => {
|
||||
test("direct launch with a space-containing executable works on this platform", async () => {
|
||||
const fixture = makeFixture();
|
||||
test.each([
|
||||
{ colors: "inherited", env: {} },
|
||||
{ colors: "conflicting", env: { NO_COLOR: "1", FORCE_COLOR: "1" } },
|
||||
])(
|
||||
"direct launch with a space-containing executable works with $colors colors",
|
||||
async ({ env }) => {
|
||||
const fixture = makeFixture();
|
||||
|
||||
const result = await runFixture({
|
||||
command: fixture.fakeDaemonNode,
|
||||
args: [fixture.assertScript, ...fixture.expectedArgs],
|
||||
shell: false,
|
||||
});
|
||||
const result = await runFixture({
|
||||
command: fixture.fakeDaemonNode,
|
||||
args: [fixture.assertScript, ...fixture.expectedArgs],
|
||||
shell: false,
|
||||
env,
|
||||
});
|
||||
|
||||
expect(result.error).toBeNull();
|
||||
expect(result.code).toBe(0);
|
||||
expect(result.stderr).toBe("");
|
||||
expect(result.stdout.trim()).toBe("ARGV_OK");
|
||||
});
|
||||
expect(result.error).toBeNull();
|
||||
expect(result.code).toBe(0);
|
||||
expect(result.stderr).toBe("");
|
||||
expect(result.stdout.trim()).toBe("ARGV_OK");
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user