From 7d732020b058fc758f5fe8b0d5e9c7edaba3a58d Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 15 Aug 2026 10:44:09 -0700 Subject: [PATCH] =?UTF-8?q?test:=20env=20restore=20runs=20per-test,=20not?= =?UTF-8?q?=20per-suite=20=E2=80=94=20the=20leak=20that=20failed=2030=20st?= =?UTF-8?q?rangers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gstack-memory-helpers saved HOME/GSTACK_HOME/PATH in beforeEach but restored in afterAll, so the last beforeEach's snapshot won and a gstack-test-engine temp dir leaked into every later file in the same process: gstack-config read the wrong store, make-pdf's child resolved Chromium under the temp cache, update-check and artifacts-init lost their real homes. afterAll is now afterEach; the config and update-check harnesses also strip GSTACK_HOME/GSTACK_STATE_ROOT from child env as a belt. --- test/gstack-memory-helpers.test.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/test/gstack-memory-helpers.test.ts b/test/gstack-memory-helpers.test.ts index 244a64976..2bc89c83f 100644 --- a/test/gstack-memory-helpers.test.ts +++ b/test/gstack-memory-helpers.test.ts @@ -11,7 +11,7 @@ * Free-tier (~50ms total). Runs in `bun test`. */ -import { describe, it, expect, beforeEach, afterAll } from "bun:test"; +import { describe, it, expect, beforeEach, afterEach } from "bun:test"; import { mkdtempSync, writeFileSync, readFileSync, existsSync, rmSync, mkdirSync, chmodSync } from "fs"; import { tmpdir } from "os"; import { join } from "path"; @@ -338,7 +338,11 @@ describe("withErrorContext", () => { process.env.GSTACK_HOME = testHome; }); - afterAll(() => { + // afterEach, not afterAll: the save happens in beforeEach, so an afterAll + // restore would put back the PREVIOUS test's temp dir (the last beforeEach + // overwrote savedHome) and leak a gstack-test-home-* dir into every test + // file that runs after this one in the same bun process. + afterEach(() => { if (savedHome === undefined) delete process.env.GSTACK_HOME; else process.env.GSTACK_HOME = savedHome; }); @@ -414,7 +418,13 @@ describe("detectEngineTier", () => { process.env.HOME = testHome; }); - afterAll(() => { + // afterEach, not afterAll: the save happens in beforeEach, so an afterAll + // restore would put back the PREVIOUS test's gstack-test-engine-* temp dir + // (the last beforeEach overwrote the saved values). That leaked + // HOME/GSTACK_HOME/PATH into every test file that ran after this one in the + // same bun process — child processes then looked for Playwright's Chromium + // cache and ~/.gstack config under a throwaway temp HOME. + afterEach(() => { if (savedHome === undefined) delete process.env.GSTACK_HOME; else process.env.GSTACK_HOME = savedHome; if (savedGbrainHome === undefined) delete process.env.GBRAIN_HOME;