Skip to content

test(utils): test_resolved_command_executes_known_command asserts on rustup's exit status and fails whenever HOME is redirected #3768

Open

Description

@KuSh

Summary

core::utils::tests::test_resolved_command_executes_known_command asserts on the exit status of a real cargo --version subprocess, which depends on the ambient rustup installation being reachable from $HOME. Redirect HOME and the test fails, even though nothing about resolved_command is broken.

This is not currently red on CI (CI's HOME is the rustup home), so it is a latent hermeticity hazard rather than a live failure.

Repro

mkdir -p /tmp/emptyhome
HOME=/tmp/emptyhome cargo test --lib test_resolved_command_executes_known_command
test core::utils::tests::test_resolved_command_executes_known_command ... FAILED

It is the only failure in the suite under that HOME (2507 passed / 1 failed).

Cause

src/core/utils.rs:867:

fn test_resolved_command_executes_known_command() {
    let output = resolved_command("cargo")
        .arg("--version")
        .output()
        .expect("resolved_command('cargo') should execute");
    assert!(output.status.success(), "cargo --version should succeed via resolved_command");
}

resolved_command resolves cargo via PATH, which is unaffected by HOME — so resolution succeeds and the test is doing its job up to that point. But the binary it finds is the rustup proxy (~/.cargo/bin/cargo), which needs $HOME/.rustup to pick a toolchain:

$ HOME=/tmp/emptyhome cargo --version
error: rustup could not choose a version of cargo to run, because one wasn't specified
       explicitly, and no default is configured.

Exit 1, so output.status.success() is false. The assertion is measuring rustup's configuration, not RTK's PATH resolution.

Why it matters

  • It blocks the obvious fix for a whole class of test-hermeticity bugs. Redirecting HOME is the standard way to stop tests reading a developer's real ~/.gemini/settings.json, ~/.claude/settings.json, ~/.config/rtk/config.toml, etc. (see the discussion on fix(json,deps): tolerate UTF-8 BOM at the remaining JSON parse sites #3751). The moment any test does that — std::env::set_var is process-wide and tests share a process — this test starts failing, intermittently and by test-execution order. No test sets HOME today, but several already mutate process-wide env (CLAUDE_CONFIG_DIR, RTK_DB_PATH, PI_CODING_AGENT_DIR, CI), so the pattern is established.
  • It breaks in environments where HOME isn't the rustup home: containers running as a different user, Nix, Bazel/sandboxed builds, or a CI job that overrides HOME.

Suggested fix

Assert the thing the test is named for — that resolved_command hands back the PATH-resolved program — without spawning a third-party binary whose success depends on the environment:

#[test]
fn test_resolved_command_executes_known_command() {
    let cmd = resolved_command("cargo");
    let resolved = resolve_binary("cargo").expect("cargo must be resolvable via PATH");
    assert_eq!(cmd.get_program(), resolved.as_os_str());
}

The sibling tool_exists tests (src/core/utils.rs:880-897) already cover resolution this way and pass fine under a redirected HOME. If actually executing something is considered valuable, pick a binary whose exit status doesn't depend on per-user configuration (true, or git --version).

Notes

Pre-existing; introduced in 46fa31c ("chore(refacto-codebase): Folders + Technical docs"), unrelated to any open PR. Surfaced while reviewing #3751.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions