Skip to content

fix(test-isolation): two process-global sinks recorded across test boundaries - #7665

Merged
proggeramlug merged 4 commits into
mainfrom
fix/opt-report-session-thread-leak
Aug 8, 2026
Merged

fix(test-isolation): two process-global sinks recorded across test boundaries#7665
proggeramlug merged 4 commits into
mainfrom
fix/opt-report-session-thread-leak

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

fix(test-isolation): two process-global sinks recorded across test boundaries.

Both follow one pattern: a process-global collector paired with a lock that only serialises the tests which take it. Any concurrently-running test that exercises the recording path — without knowing the collector exists — wrote into the lock-holder's snapshot.

  • opt_reportFORCED and the Mutex<Vec<Entry>> sink are global; Session drains on entry and drop but cannot stop a neighbour emitting mid-test. only_the_return_position_is_marked_served asserts rows.len() == 2 and failed at 3.
  • ext_registryUSED_PROVIDERS is a process-wide Mutex<HashSet>; record_ffi_call fires from any lowering of an ext symbol. ext_prefix_net_does_not_over_match asserts the set is empty after an unlisted symbol and failed with ioredis still in it.

Both are pre-existing and both were surfaced by #7662 (Layer 1 slice 7), which added child_process and Proxy/Reflect lowering tests and so changed the parallel schedule: only_the_return_position_is_marked_served was 0/14 on main and 2/18 on that branch; ext_prefix_net_does_not_over_match was 1/20.

Diagnosed from the extra row, not from the timing. A 1-in-6 flake invites a retry; the value 3-instead-of-2 says a neighbour's entry is in the snapshot, which names the mechanism directly.

Recording is now narrowed to the thread holding the guard — test_support::recording_thread_is_current() for opt_report, ProviderTestGuard + provider_recording_permitted() for ext_registry. Production is untouched in both: the opt_report check sits inside the #[cfg(test)] forced branch and the env-var path is unchanged, and PROVIDER_TEST_THREAD is #[cfg(test)] with the predicate returning true whenever no provider test is running.

Verified 0 failures in 25 consecutive cargo test -p perry-codegen --lib --no-fail-fast runs on top of #7662, where the pair reproduced at 3/38 before.

Summary by CodeRabbit

  • Bug Fixes

    • Improved test isolation to prevent concurrent tests from affecting one another’s recorded results.
    • Ensured provider and optimization-report assertions remain accurate when tests run in parallel.
    • Production behavior remains unchanged.
  • Documentation

    • Added changelog details covering the test-isolation improvements.
  • Chores

    • Incremented the release version to 0.5.1377.

Ralph Küpper added 4 commits August 8, 2026 23:17
opt_report's gate (FORCED) and sink are process-global, but Session's lock
only serialises tests that TAKE a Session. A concurrently-running test that
lowers code without one therefore emitted into the holder's sink, and the
holder's snapshot saw a neighbour's rows.

Observed, not theoretical: only_the_return_position_is_marked_served asserts
rows.len() == 2 and failed at 3 about one run in six once #7662 added lowering
tests, which changed the parallel schedule. 0/14 on main before that PR, 2/18
on it -- the extra row is what identified the mechanism, not the timing.

Recording is now additionally narrowed to the thread that opened the Session.
Production is unaffected: the thread check is inside the #[cfg(test)] forced
branch, and the env-var path is untouched.

Claude-Session: https://claude.ai/code/session_01Y1QZ5wUP9gRSwpiweT4Wix
…lock

USED_PROVIDERS is process-wide but PROVIDER_TEST_LOCK only serialises tests
that TAKE it, so a concurrently-running test that lowers any code touching an
ext symbol added providers to the holder's set.

Observed: ext_prefix_net_does_not_over_match asserts the set is empty after an
unlisted symbol and failed 1 run in 20 once #7662 added child_process lowering
tests, which call record_ffi_call.

ProviderTestGuard takes the lock AND claims the thread; record_ffi_call skips
the global set when another thread holds a provider test. Production is
unaffected -- PROVIDER_TEST_THREAD is #[cfg(test)] and the predicate returns
true whenever no provider test is running.

Claude-Session: https://claude.ai/code/session_01Y1QZ5wUP9gRSwpiweT4Wix
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ebbba5d-b62f-42db-a18e-29ae84c8371e

📥 Commits

Reviewing files that changed from the base of the PR and between 7bde3de and f0d2b68.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • CLAUDE.md
  • Cargo.toml
  • changelog.d/7665-test-isolation-global-sinks.md
  • crates/perry-codegen/src/ext_registry.rs
  • crates/perry-codegen/src/opt_report/mod.rs

📝 Walkthrough

Walkthrough

The change isolates opt_report and ext_registry test recording by thread ownership. Provider tests now use ProviderTestGuard. Project version metadata and the changelog are updated.

Changes

Test isolation

Layer / File(s) Summary
Optimization report thread ownership
crates/perry-codegen/src/opt_report/mod.rs
Test recording is limited to the thread that owns the active Session. Session creation claims ownership, and Drop releases it.
Provider recording thread ownership
crates/perry-codegen/src/ext_registry.rs
Provider recording checks the owning test thread. Provider routing tests use ProviderTestGuard.
Release metadata
CLAUDE.md, Cargo.toml, changelog.d/7665-test-isolation-global-sinks.md
The project version changes to 0.5.1377. The changelog documents the test-isolation fixes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: bug

Suggested reviewers: jdalton

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/opt-report-session-thread-leak

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug
proggeramlug merged commit cc7ce41 into main Aug 8, 2026
0 of 13 checks passed
@proggeramlug
proggeramlug deleted the fix/opt-report-session-thread-leak branch August 8, 2026 21:23
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