Skip to content

fix(therock): stop python-resolver tests mutating the process PATH - #253

Merged
rominf merged 2 commits into
mainfrom
fix/python-resolver-test-env-isolation
Aug 14, 2026
Merged

fix(therock): stop python-resolver tests mutating the process PATH#253
rominf merged 2 commits into
mainfrom
fix/python-resolver-test-env-isolation

Conversation

@rominf

@rominf rominf commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator
  • If this PR fixes a bug, searched tests/e2e-cucumber/expectations.toml for the fixed ticket ID and removed/narrowed any now-stale xfail rows. (No matching rows.)

Summary

  • Pass the Python resolver's environment — the ROCM_CLI_PYTHON override and the directories to search — in as a value instead of reading it at the use site.
  • The two tests that used to steer the resolver by overwriting PATH for the whole process now hand it a fixture directory, so both unsafe set_var blocks are gone rather than serialized behind a lock.
  • Why: those tests made unrelated tests fail. cargo test -p rocm --bin rocm failed in 11 of 20 runs on a clean main because of this.
  • Risk: low. No behaviour change — resolve_python_launcher reads exactly the same two variables, just once at entry instead of at each use site. Production is unaffected; the seam exists so tests do not need the process environment.

Root cause

cargo test runs every test as a thread in one process. python_launcher_prefers_path_python_before_saved_managed_python and python_launcher_prefers_path_python_over_managed_when_venv_capable set PATH to a single fixture directory for the duration of resolve_python_launcher, then restore it. That window is process-wide: while it is open, every other test also has no usable PATH, and any test that spawns a PATH-resolved binary fails with ENOENT.

The visible casualty was therock::tests::extracting_the_sdk_archive_removes_it, failing with:

Error: failed to launch tar

Caused by:
    No such file or directory (os error 2)

tar was installed the whole time. That test spawns tar twice and only the second spawn failed, which is the window opening between them.

The mutex the tests already held only serialized them against each other, not against the ~450 other tests sharing the process, so it could not have helped. Removing the global mutation is what fixes it.

Verification

20 consecutive cargo test -p rocm --bin rocm runs:

before after
extracting_the_sdk_archive_removes_it 11/20 0/20

Root cause confirmed before fixing, by running the same 20 iterations with only these two tests skipped (--skip python_launcher_prefers_path): the tar failure disappeared, isolating it to them.

Also run: cargo clippy --locked --workspace --all-targets -- -D warnings, cargo clippy --locked -p e2e-cucumber --test e2e -- -D warnings, cargo test --workspace --all-targets --exclude e2e-cucumber, prek run --all-files.

Notes for reviewers

  • Why this did not show up in CI. The Linux test job runs cargo nextest, which is process-per-test and therefore immune. The Windows job runs plain cargo test, but these two tests are #[cfg(unix)]. The pain is local: the pre-push hook runs cargo test, and contributors have been working around it with SKIP=cargo-test git push.
  • New test. python_path_search_only_uses_the_given_directories pins the property that keeps this from coming back — with no search directories the resolver finds nothing, even though the real PATH certainly has a python on it. It fails if anyone reintroduces an implicit PATH read.
  • Left alone deliberately. python_venv_probe_temp_root_uses_windows_temp_env still mutates TEMP/TMP/LOCALAPPDATA process-wide and still takes the mutex. It is the same class of hazard on the Windows cargo test lane, but it plays no part in this failure and I cannot verify a Windows fix from here. Worth a follow-up.

rominf added 2 commits August 13, 2026 07:50
Steps that assert on rocm's exit code printed only stdout, and rocm
reports its failures on stderr. A failed serve therefore panicked with
"rocm serve failed:" followed by nothing at all, which is how the
MI300X lane ended up with a red scenario nobody can diagnose from CI
(EAI-8031).

run_rocm returns stderr already -- the five assertion sites just bound
it to `_`. Replace them with a run_rocm_ok helper that panics through a
shared cli_failure_report: invocation, exit code, and both streams, each
labelled, each marked "(empty)" rather than omitted. The distinction
matters -- "the CLI said nothing" and "the harness dropped the output"
are different diagnoses, and telling them apart is the whole point.

Two serve steps defer their rc assertion to a later Then step, so they
now carry stderr in the world alongside the rc they already store.

The formatter lives in the library, where `cargo test -p e2e-cucumber
--lib` covers it in CI; the harness target's own tests never run.

Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
`cargo test` runs every test as a thread in one process. Two python
resolver tests overwrote `PATH` process-wide to point the interpreter
search at a fixture directory, so for the duration of each resolve every
other test lost its `PATH` too, and any test that happened to spawn a
PATH-resolved binary in that window failed with ENOENT. It surfaced as
`extracting_the_sdk_archive_removes_it` dying with "failed to launch
tar" in 11 of 20 local suite runs; `tar` was installed the whole time.

Pass the resolver's environment — the `ROCM_CLI_PYTHON` override and the
directories to search — in as a value instead of reading it at the use
site. The tests now hand it their fixture directory and never touch the
process environment, so both `unsafe` `set_var` blocks are gone rather
than serialized behind a lock.

After the change the tar failure does not reproduce in 20 consecutive
suite runs.

Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
@rominf
rominf requested a review from a team as a code owner August 13, 2026 13:48

@r0x0r r0x0r left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice root-cause writeup. The key insight — the existing mutex only serialized the two PATH-mutating tests against each other, never against the ~450 other tests sharing the process — is exactly right, and switching to injected search directories (PythonResolverEnv) is the correct fix rather than adding more locking. Production behavior is preserved (from_process_env() reads the same two variables, just once at entry), the unsafe { set_var } blocks are gone, and python_path_search_only_uses_the_given_directories pins the property so an implicit PATH read cannot creep back. LGTM.

Two non-blocking notes:

  1. CI red checks are not from this change. E2E tests (GPU) and E2E tests (Strix Halo, Windows) both fail on the pre-existing serve-hf-checkpoint-inference "1 unexpected failure(s)" regression — same signature seen on several other unrelated open branches. Your new cli_failure_report is actually visible in those logs now (rocm serve ... failed (rc=1)), which is a nice validation that the helper works. All other checks (clippy, windows-build-and-test, affected tests, signatures) are green.

  2. Scope. The cli_failure_report / run_rocm_ok / cli_stderr e2e diagnostics (EAI-8031) are a good change but orthogonal to the python-resolver PATH fix — different subsystem, different ticket. Per the one-logical-change-per-PR convention they would be easier to land/revert independently. Happy either way; flagging for a possible follow-up split rather than blocking on it.

@rominf
rominf added this pull request to the merge queue Aug 14, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 14, 2026
@rominf
rominf added this pull request to the merge queue Aug 14, 2026
Merged via the queue into main with commit 0063ef1 Aug 14, 2026
24 of 28 checks passed
@rominf
rominf deleted the fix/python-resolver-test-env-isolation branch August 14, 2026 13:43
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