diff --git a/src/test/mock/clitools.rs b/src/test/mock/clitools.rs index fe5f834844b..1c115561cae 100644 --- a/src/test/mock/clitools.rs +++ b/src/test/mock/clitools.rs @@ -547,6 +547,17 @@ impl Config { } } + #[track_caller] + pub fn expect_stdout_ok_with_env(&self, args: &[&str], env: &[(&str, &str)], expected: &str) { + let out = self.run(args[0], &args[1..], env); + if !out.ok || !out.stdout.contains(expected) { + print_command(args, &out); + println!("expected.ok: true"); + print_indented("expected.stdout.contains", expected); + panic!(); + } + } + #[track_caller] pub fn expect_not_stdout_ok(&self, args: &[&str], expected: &str) { let out = self.run(args[0], &args[1..], &[]); diff --git a/tests/suite/cli_rustup.rs b/tests/suite/cli_rustup.rs index 9a6adde7a4d..74aa7221366 100644 --- a/tests/suite/cli_rustup.rs +++ b/tests/suite/cli_rustup.rs @@ -2376,6 +2376,130 @@ fn only_toml_in_rust_toolchain_toml() { }); } +/// Checks that `rust-toolchain.toml` configs can be overridden by `rustup override set` or ` +`. +/// See: +#[test] +fn rust_toolchain_toml_with_rustup_override() { + test(&|config| { + config.with_scenario(Scenario::SimpleV2, &|config| { + config.expect_ok(&["rustup", "default", "stable"]); + + let stable = "hash-stable-1.1.0"; + config.expect_stdout_ok(&["rustc", "--version"], stable); + + config.expect_ok(&["rustup", "override", "set", "beta"]); + + let cwd = config.current_dir(); + let toolchain_file = cwd.join("rust-toolchain.toml"); + raw::write_file( + &toolchain_file, + r#" + [toolchain] + channel = "nightly" + components = [ "rls" ] + "#, + ) + .unwrap(); + + let beta = "hash-beta-1.2.0"; + config.expect_stdout_ok(&["rustc", "--version"], beta); + config.expect_stdout_ok(&["rls", "--version"], beta); + + config.expect_stderr_ok(&["rls", "+stable", "--version"], stable); + }) + }); +} + +/// Checks that `rust-toolchain.toml` configs can be overridden by `RUSTUP_TOOLCHAIN`. +/// See: +#[test] +fn rust_toolchain_toml_with_rustup_toolchain() { + test(&|config| { + config.with_scenario(Scenario::SimpleV2, &|config| { + config.expect_err( + &["rustc", "--version"], + "rustup could not choose a version of rustc to run", + ); + + let cwd = config.current_dir(); + let toolchain_file = cwd.join("rust-toolchain.toml"); + raw::write_file( + &toolchain_file, + r#" + [toolchain] + channel = "nightly" + components = [ "rls" ] + "#, + ) + .unwrap(); + + let env = &[("RUSTUP_TOOLCHAIN", "beta")]; + let beta = "hash-beta-1.2.0"; + config.expect_stdout_ok_with_env(&["rustc", "--version"], env, beta); + config.expect_stdout_ok_with_env(&["rls", "--version"], env, beta); + + // At this point, `nightly` is still NOT installed. + config.expect_not_stderr_ok(&["rustup", "toolchain", "list"], "nightly"); + }) + }); +} + +/// Checks that `rust-toolchain.toml` configs can override `rustup override set` at different directories. +/// See: +#[test] +fn rust_toolchain_toml_with_rustup_override_parent_dir() { + test(&|config| { + config.with_scenario(Scenario::SimpleV2, &|config| { + config.expect_err( + &["rustc", "--version"], + "rustup could not choose a version of rustc to run", + ); + + // "." -> nightly, no rls + config.expect_ok(&["rustup", "override", "set", "nightly"]); + + // "./inner" -> beta + rls + let inner = &config.current_dir().join("inner"); + std::fs::create_dir(inner).unwrap(); + config.change_dir(inner, &|config| { + let cwd = config.current_dir(); + let toolchain_file = cwd.join("rust-toolchain.toml"); + raw::write_file( + &toolchain_file, + r#" + [toolchain] + channel = "beta" + components = [ "rls" ] + "#, + ) + .unwrap(); + + let beta = "hash-beta-1.2.0"; + config.expect_stdout_ok(&["rustc", "--version"], beta); + config.expect_stdout_ok(&["rls", "--version"], beta); + }); + + // "./inner/inner" -> stable, no rls + let inner2 = &inner.join("inner"); + std::fs::create_dir(inner2).unwrap(); + config.change_dir(inner2, &|config| { + config.expect_ok(&["rustup", "override", "set", "stable"]); + + let stable = "hash-stable-1.1.0"; + config.expect_stdout_ok(&["rustc", "--version"], stable); + // The `rustup override set` in this directory stops + // the `rust-toolchain.toml` in the parent directory from working. + config.expect_component_not_executable("rls") + }); + + // "." -> nightly, no rls + let nightly = "hash-nightly-2"; + config.expect_stdout_ok(&["rustc", "--version"], nightly); + config.expect_component_not_executable("rls"); + }) + }); +} + /// Checks that a warning occurs if both `rust-toolchain` and `rust-toolchain.toml` files exist #[test] fn warn_on_duplicate_rust_toolchain_file() {