Skip to content

fix(test): restore SENTRY_CONFIG_DIR in afterEach instead of deleting#240

Closed
betegon wants to merge 4 commits intomainfrom
fix/test-env-var-race
Closed

fix(test): restore SENTRY_CONFIG_DIR in afterEach instead of deleting#240
betegon wants to merge 4 commits intomainfrom
fix/test-env-var-race

Conversation

@betegon
Copy link
Member

@betegon betegon commented Feb 13, 2026

Summary

Three test files were deleting process.env.SENTRY_CONFIG_DIR in their afterEach hooks without restoring the value originally set by preload.ts. Since Bun runs test files in parallel, this created a race condition: test files that capture the env var at module scope (like region.test.ts, config.test.ts, concurrent.test.ts) would get undefined if their module loaded after one of these deletes ran.

This caused 37 test failures across all recent PRs (#238, #237, #226, #221, #202) — likely triggered by a GHA runner image update (20260201.15.120260209.23.1) that changed process scheduling enough to hit the race consistently.

Changes

Save the original SENTRY_CONFIG_DIR value in beforeEach and restore it in afterEach, matching the pattern already used by schema.test.ts and fix.test.ts. Three files fixed:

  • test/lib/version-check.test.ts (2 describe blocks)
  • test/lib/db/project-cache.test.ts
  • test/lib/db/install-info.test.ts

Test Plan

Ran the full unit test suite locally — all 37 previously-failing tests now pass. The remaining local failures (dsn/cache.test.ts SQLITE_IOERR_VNODE errors) are pre-existing on main.

Three test files deleted process.env.SENTRY_CONFIG_DIR in afterEach
without restoring the value set by preload.ts. Since Bun runs test
files in parallel, this caused a race condition: other test files
that capture the env var at module scope would get undefined if
their module loaded after one of these deletes ran.

Save the original value in beforeEach and restore it in afterEach,
matching the pattern already used by schema.test.ts and fix.test.ts.
@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (formatters) Add Seer fixability score to issue list and detail views by betegon in #234

Bug Fixes 🐛

Telemetry

  • Use SDK session integration instead of manual management by BYK in #232
  • Correct runtime context for Bun binary by BYK in #231

Other

  • (test) Restore SENTRY_CONFIG_DIR in afterEach instead of deleting by betegon in #240

🤖 This preview updates automatically when you update the PR.

Extend the save/restore pattern to every test file that modifies
process.env.SENTRY_CONFIG_DIR. Also move module-scope env var
captures into beforeEach hooks so they read the value at hook time
rather than at module evaluation time.

Files fixed:
- test/lib/api-client.test.ts
- test/lib/api-client.seer.test.ts
- test/lib/api-client.multiregion.test.ts
- test/commands/issue/utils.test.ts
- test/lib/dsn/cache.test.ts
- test/lib/dsn/detector.test.ts
- test/lib/config.test.ts (module-scope -> beforeEach)
- test/lib/region.test.ts (module-scope -> beforeEach)
- test/lib/db/concurrent.test.ts (module-scope -> beforeEach)
…urrent tests

Add lockConfigDir() and lockFetch() helpers that use Object.defineProperty
to prevent concurrent test files from mutating SENTRY_CONFIG_DIR and
globalThis.fetch between async boundaries. This fixes the DB singleton
auto-invalidation race where another file's beforeEach/afterEach changes
the config dir mid-test, causing getDatabase() to open the wrong database
and lose auth tokens.

Fixes: api-client 401 retry tests (3), config refreshToken test (1)
Object.defineProperty with configurable:true is bypassed by `delete`
(which concurrent test files do in afterEach), and configurable:false
causes `delete` to throw in Bun. Switch to a Proxy on process.env
that intercepts get/set/delete of SENTRY_CONFIG_DIR — survives both
`delete` and re-assignment from concurrent test files.
@BYK
Copy link
Member

BYK commented Feb 13, 2026

Superceded by #242

@BYK BYK closed this Feb 13, 2026
BYK added a commit that referenced this pull request Feb 13, 2026
…ollution (#242)

## Summary

Fixes 37 test failures caused by the Ubuntu 24.04 runner image upgrade
(`20260201.15.1` → `20260209.23.1`, kernel 6.11 → 6.14) that changed
`readdir` ordering, exposing a latent env var pollution bug.

## Root Cause

Bun runs test files **sequentially in one thread** (load → run all tests
→ load next file). Several test files unconditionally `delete
process.env.SENTRY_CONFIG_DIR` in their `afterEach` hooks. When the next
file loads, its module-level code captures `undefined`, causing
`join(undefined, ...)` → `TypeError`.

The runner image upgrade changed the kernel which changed file discovery
order, putting "deleting" files before "capturing" files.

## Changes

- **`test/helpers.ts`**: Added `useTestConfigDir()` helper that creates
a unique temp directory in `beforeEach`, points `SENTRY_CONFIG_DIR` at
it, and **restores** (never deletes) the original value in `afterEach`.
Also handles `closeDatabase()` and temp dir cleanup.
- **11 test files migrated** to use `useTestConfigDir()`, eliminating:
- 3 files that unconditionally deleted `SENTRY_CONFIG_DIR` (root cause)
- 3 files with fragile module-level `process.env[CONFIG_DIR_ENV_VAR]!`
captures
- 2 files with `if (original) restore else delete` patterns (off-by-one
on falsy check)
  - 2 files missing env var restore in `afterEach`
- **`AGENTS.md`**: Added "Test Environment Isolation" section
documenting the pattern and anti-patterns

Net: **-87 lines** (157 added, 244 removed) — less boilerplate, more
safety.

## Verification

- `bun run typecheck` — passes
- `bun run lint` — passes  
- `bun run test:unit` — **1545 tests pass, 0 failures**

Supercedes #240
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.

2 participants