Skip to content

test(web): isolate startup fixtures from inherited npm_execpath casing - #186

Merged
lnieuwenhuis merged 1 commit into
stagingfrom
fix/audit-startup-test-isolation
Sep 17, 2026
Merged

lnieuwenhuis merged 1 commit into
stagingfrom
fix/audit-startup-test-isolation

Conversation

@lnieuwenhuis

Copy link
Copy Markdown
Owner

Problem

The final-verification full suite (pnpm --filter @macro-tracker/web test, Windows, work/final-verification/web-vitest-rerun.log) failed exactly 3 tests in apps/web/tests/unit/startup-process.test.ts:

  • runs migrations then serves and terminates on kill on Windows — ENOENT ...\macro-startup-*\migration
  • runs the package manager entry provided through npm_execpath — same migration marker missing
  • fails startup without serving when migrations fail — ready resolved instead of rejecting

Direct vitest runs of the same file passed, so the failure depended on how the suite was launched. It reproduced with no backend listening (no PORT/BACKEND_URL involvement).

Root cause

pnpm run on Windows exposes the package manager entry as NPM_EXECPATH (uppercase) alongside NPM_NODE_EXECPATH; pnpm exec/direct vitest do not. The fixture's exact-case delete env.npm_execpath left the inherited uppercase key in the child environment, so the copied launcher preferred the real pnpm.cjs over the fixture shim/entry. Migrations then exited 0 without writing the migration marker, and the exit-7 fixture never failed.

Evidence from the instrumented reproduction:

  • Launcher env dump: npm_execpath=C:\...\corepack\v1\pnpm\10.28.2\bin\pnpm.cjs, with hasKey:false for the lowercase name and keys:["NPM_EXECPATH","NPM_NODE_EXECPATH"] at spawn time.
  • getPackageManagerCommand resolved node ...pnpm.cjs --filter @macro-tracker/db db:migrate for both runner modes.
  • Env-key dump under pnpm test (script) vs pnpm exec vitest (uppercase vs none) — see work/startup-final/ logs referenced below.

Fix (test-only, no application code)

  • Added removeCaseInsensitiveEnvKey(env, "npm_execpath") so every case variant of the inherited variable is removed before the runner is selected; the node-entry branch then sets its own entry, the path-shim branch falls back to PATH.
  • Added two regression tests that simulate an inherited case-variant npm_execpath (decoy .cjs entry that exits 0 without recording migrations) for both runner modes, restoring the inherited value afterwards.
  • No test disabled, skipped, or weakened; production launcher behavior unchanged.

Verification (Windows, Node 24.20.0 / pnpm 10.28.2)

Check Result
Pre-fix pnpm --filter @macro-tracker/web test -- tests/unit/startup-process.test.ts 5 failed / 6 passed / 2 skipped (3 reported + 2 new regressions)
Post-fix same command 13 tests: 11 passed / 2 skipped (POSIX signal cases only)
Post-fix same command with final-verifier env (PORT/BACKEND_URL/BACKEND_ENABLE_TEST_ROUTES/APP_URL/dummy DB + secrets) 11 passed / 2 skipped
Post-fix full suite (88 files) with disposable Postgres 16 + backend built from this branch (port 4015, test-faults) 88 files passed, 574 passed / 2 skipped / 0 failed; backend stopped and DB container removed in the same command
pnpm --filter @macro-tracker/web typecheck / lint clean

Logs: C:/Users/lnieu/Documents/macro-tracker-audit-20260917/work/startup-final/ (prefix-targeted2.log, postfix-targeted.log, postfix-verifierenv-targeted.log, postfix-full-suite2.log).

Linux CI still runs the POSIX signal cases; the fixture regression is meaningful on Windows and harmless on POSIX, where environment names are case-sensitive.

pnpm script invocations on Windows expose npm_execpath as NPM_EXECPATH. The fixture's exact-case delete left the inherited key in the child environment, so the launcher used the real pnpm instead of the fixture shim/entry: migrations exited 0 without writing the marker and the exit-7 gate served anyway. Remove every case variant before the runner is selected and cover both runner modes with a regression that restores the inherited value.
@lnieuwenhuis
lnieuwenhuis merged commit 2582e61 into staging Sep 17, 2026
7 checks passed
lnieuwenhuis added a commit that referenced this pull request Sep 17, 2026
chore: promote staging 3.6.0 (audit remediation, PRs #173-#186) to main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant