Previously, the profile to use when installing a new toolchain had to be set globally through `rustup set profile`, or at rustup-init time. Sometimes this is inconvenient, because you only want to use a particular profile when installing a specific toolchain. This patch allows users to pass `--profile` to `rustup install` to override the profile used for that one install. Fixes #2004.
1258 lines
39 KiB
Rust
1258 lines
39 KiB
Rust
//! Test cases of the rustup command, using v2 manifests, mostly
|
|
//! derived from multirust/test-v2.sh
|
|
|
|
pub mod mock;
|
|
|
|
use crate::mock::clitools::{
|
|
self, expect_component_executable, expect_component_not_executable, expect_err,
|
|
expect_not_stderr_ok, expect_not_stdout_ok, expect_ok, expect_ok_ex, expect_stderr_ok,
|
|
expect_stdout_ok, set_current_dist_date, this_host_triple, Config, Scenario,
|
|
};
|
|
use std::fs;
|
|
use std::io::Write;
|
|
|
|
use rustup::dist::dist::TargetTriple;
|
|
|
|
macro_rules! for_host {
|
|
($s: expr) => {
|
|
&format!($s, this_host_triple())
|
|
};
|
|
}
|
|
|
|
pub fn setup(f: &dyn Fn(&mut Config)) {
|
|
clitools::setup(Scenario::SimpleV2, f);
|
|
}
|
|
|
|
pub fn setup_complex(f: &dyn Fn(&mut Config)) {
|
|
clitools::setup(Scenario::UnavailableRls, f);
|
|
}
|
|
|
|
#[test]
|
|
fn rustc_no_default_toolchain() {
|
|
setup(&|config| {
|
|
expect_err(config, &["rustc"], "no default toolchain configured");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn expected_bins_exist() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "1.3.0");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn install_toolchain_from_channel() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
expect_ok(config, &["rustup", "default", "beta"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-beta-1.2.0");
|
|
expect_ok(config, &["rustup", "default", "stable"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.1.0");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn install_toolchain_from_archive() {
|
|
clitools::setup(Scenario::ArchivesV2, &|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly-2015-01-01"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-1");
|
|
expect_ok(config, &["rustup", "default", "beta-2015-01-01"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-beta-1.1.0");
|
|
expect_ok(config, &["rustup", "default", "stable-2015-01-01"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.0.0");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn install_toolchain_from_version() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "1.1.0"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.1.0");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn install_with_profile() {
|
|
setup_complex(&|config| {
|
|
// Start with a config that uses the "complete" profile
|
|
set_current_dist_date(config, "2015-01-01");
|
|
expect_ok(config, &["rustup", "set", "profile", "complete"]);
|
|
|
|
// Installing with minimal profile should only install rustc
|
|
expect_ok(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"toolchain",
|
|
"install",
|
|
"--profile",
|
|
"minimal",
|
|
"nightly",
|
|
"--no-self-update",
|
|
],
|
|
);
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
|
|
expect_component_executable(config, "rustup");
|
|
expect_component_executable(config, "rustc");
|
|
expect_component_not_executable(config, "cargo");
|
|
|
|
// After an update, we should _still_ only have the profile-dictated components
|
|
set_current_dist_date(config, "2015-01-02");
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
|
|
expect_component_executable(config, "rustup");
|
|
expect_component_executable(config, "rustc");
|
|
expect_component_not_executable(config, "cargo");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn default_existing_toolchain() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_stderr_ok(
|
|
config,
|
|
&["rustup", "default", "nightly"],
|
|
for_host!("using existing install for 'nightly-{0}'"),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn update_channel() {
|
|
clitools::setup(Scenario::ArchivesV2, &|config| {
|
|
set_current_dist_date(config, "2015-01-01");
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-1");
|
|
set_current_dist_date(config, "2015-01-02");
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn list_toolchains() {
|
|
clitools::setup(Scenario::ArchivesV2, &|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "update", "beta-2015-01-01", "--no-self-update"],
|
|
);
|
|
expect_stdout_ok(config, &["rustup", "toolchain", "list"], "nightly");
|
|
expect_stdout_ok(
|
|
config,
|
|
&["rustup", "toolchain", "list", "-v"],
|
|
"(default)\t",
|
|
);
|
|
expect_stdout_ok(
|
|
config,
|
|
&["rustup", "toolchain", "list", "--verbose"],
|
|
"(default)\t",
|
|
);
|
|
expect_stdout_ok(config, &["rustup", "toolchain", "list"], "beta-2015-01-01");
|
|
expect_stdout_ok(config, &["rustup", "toolchain", "list", "-v"], "\t");
|
|
expect_stdout_ok(config, &["rustup", "toolchain", "list", "--verbose"], "\t");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn list_toolchains_with_bogus_file() {
|
|
// #520
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
|
|
let name = "bogus_regular_file.txt";
|
|
let path = config.rustupdir.join("toolchains").join(name);
|
|
rustup::utils::utils::write_file(name, &path, "").unwrap();
|
|
expect_stdout_ok(config, &["rustup", "toolchain", "list"], "nightly");
|
|
expect_not_stdout_ok(config, &["rustup", "toolchain", "list"], name);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn list_toolchains_with_none() {
|
|
setup(&|config| {
|
|
expect_stdout_ok(
|
|
config,
|
|
&["rustup", "toolchain", "list"],
|
|
"no installed toolchains",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_toolchain() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_ok(config, &["rustup", "toolchain", "remove", "nightly"]);
|
|
expect_ok(config, &["rustup", "toolchain", "list"]);
|
|
expect_stdout_ok(
|
|
config,
|
|
&["rustup", "toolchain", "list"],
|
|
"no installed toolchains",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_remove_multiple_toolchains() {
|
|
fn go(add: &str, rm: &str) {
|
|
setup(&|config| {
|
|
let tch1 = "beta";
|
|
let tch2 = "nightly";
|
|
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "toolchain", add, tch1, tch2, "--no-self-update"],
|
|
);
|
|
expect_ok(config, &["rustup", "toolchain", "list"]);
|
|
expect_stdout_ok(config, &["rustup", "toolchain", "list"], tch1);
|
|
expect_stdout_ok(config, &["rustup", "toolchain", "list"], tch2);
|
|
|
|
expect_ok(config, &["rustup", "toolchain", rm, tch1, tch2]);
|
|
expect_ok(config, &["rustup", "toolchain", "list"]);
|
|
expect_not_stdout_ok(config, &["rustup", "toolchain", "list"], tch1);
|
|
expect_not_stdout_ok(config, &["rustup", "toolchain", "list"], tch2);
|
|
});
|
|
}
|
|
|
|
for add in &["add", "update", "install"] {
|
|
for rm in &["remove", "uninstall"] {
|
|
go(add, rm);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn remove_default_toolchain_err_handling() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "toolchain", "remove", "nightly"]);
|
|
expect_err(
|
|
config,
|
|
&["rustc"],
|
|
for_host!("toolchain 'nightly-{0}' is not installed"),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_override_toolchain_err_handling() {
|
|
setup(&|config| {
|
|
let tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
config.change_dir(tempdir.path(), &|| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "override", "add", "beta"]);
|
|
expect_ok(config, &["rustup", "toolchain", "remove", "beta"]);
|
|
expect_stderr_ok(
|
|
config,
|
|
&["rustc", "--version"],
|
|
"info: installing component",
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn file_override_toolchain_err_handling() {
|
|
setup(&|config| {
|
|
let cwd = config.current_dir();
|
|
let toolchain_file = cwd.join("rust-toolchain");
|
|
rustup::utils::raw::write_file(&toolchain_file, "beta").unwrap();
|
|
expect_stderr_ok(
|
|
config,
|
|
&["rustc", "--version"],
|
|
"info: installing component",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn plus_override_toolchain_err_handling() {
|
|
setup(&|config| {
|
|
expect_err(
|
|
config,
|
|
&["rustc", "+beta"],
|
|
for_host!("toolchain 'beta-{0}' is not installed"),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn bad_sha_on_manifest() {
|
|
setup(&|config| {
|
|
// Corrupt the sha
|
|
let sha_file = config.distdir.join("dist/channel-rust-nightly.toml.sha256");
|
|
let sha_str = fs::read_to_string(&sha_file).unwrap();
|
|
let mut sha_bytes = sha_str.into_bytes();
|
|
sha_bytes[..10].clone_from_slice(b"aaaaaaaaaa");
|
|
let sha_str = String::from_utf8(sha_bytes).unwrap();
|
|
rustup::utils::raw::write_file(&sha_file, &sha_str).unwrap();
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn bad_sha_on_installer() {
|
|
setup(&|config| {
|
|
// Since the v2 sha's are contained in the manifest, corrupt the installer
|
|
let dir = config.distdir.join("dist/2015-01-02");
|
|
for file in fs::read_dir(&dir).unwrap() {
|
|
let file = file.unwrap();
|
|
let path = file.path();
|
|
let filename = path.to_string_lossy();
|
|
if filename.ends_with(".tar.gz") || filename.ends_with(".tar.xz") {
|
|
rustup::utils::raw::write_file(&path, "xxx").unwrap();
|
|
}
|
|
}
|
|
expect_err(config, &["rustup", "default", "nightly"], "checksum failed");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn install_override_toolchain_from_channel() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "override", "add", "nightly"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
expect_ok(config, &["rustup", "override", "add", "beta"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-beta-1.2.0");
|
|
expect_ok(config, &["rustup", "override", "add", "stable"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.1.0");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn install_override_toolchain_from_archive() {
|
|
clitools::setup(Scenario::ArchivesV2, &|config| {
|
|
expect_ok(config, &["rustup", "override", "add", "nightly-2015-01-01"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-1");
|
|
expect_ok(config, &["rustup", "override", "add", "beta-2015-01-01"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-beta-1.1.0");
|
|
expect_ok(config, &["rustup", "override", "add", "stable-2015-01-01"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.0.0");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn install_override_toolchain_from_version() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "override", "add", "1.1.0"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.1.0");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn override_overrides_default() {
|
|
setup(&|config| {
|
|
let tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
config.change_dir(tempdir.path(), &|| {
|
|
expect_ok(config, &["rustup", "override", "add", "beta"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-beta-1.2.0");
|
|
});
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn multiple_overrides() {
|
|
setup(&|config| {
|
|
let tempdir1 = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
let tempdir2 = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
config.change_dir(tempdir1.path(), &|| {
|
|
expect_ok(config, &["rustup", "override", "add", "beta"]);
|
|
});
|
|
config.change_dir(tempdir2.path(), &|| {
|
|
expect_ok(config, &["rustup", "override", "add", "stable"]);
|
|
});
|
|
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
|
|
config.change_dir(tempdir1.path(), &|| {
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-beta-1.2.0");
|
|
});
|
|
config.change_dir(tempdir2.path(), &|| {
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.1.0");
|
|
});
|
|
});
|
|
}
|
|
|
|
// #316
|
|
#[test]
|
|
#[cfg(windows)]
|
|
fn override_windows_root() {
|
|
setup(&|config| {
|
|
use std::path::{Component, PathBuf};
|
|
|
|
let cwd = config.current_dir();
|
|
let prefix = cwd.components().next().unwrap();
|
|
let prefix = match prefix {
|
|
Component::Prefix(p) => p,
|
|
_ => panic!(),
|
|
};
|
|
|
|
// This value is probably "C:"
|
|
// Really sketchy to be messing with C:\ in a test...
|
|
let prefix = prefix.as_os_str().to_str().unwrap();
|
|
let prefix = format!("{}\\", prefix);
|
|
config.change_dir(&PathBuf::from(&prefix), &|| {
|
|
expect_ok(config, &["rustup", "default", "stable"]);
|
|
expect_ok(config, &["rustup", "override", "add", "nightly"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
expect_ok(config, &["rustup", "override", "remove"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.1.0");
|
|
});
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn change_override() {
|
|
setup(&|config| {
|
|
let tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
config.change_dir(tempdir.path(), &|| {
|
|
expect_ok(config, &["rustup", "override", "add", "nightly"]);
|
|
expect_ok(config, &["rustup", "override", "add", "beta"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-beta-1.2.0");
|
|
});
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_override_no_default() {
|
|
setup(&|config| {
|
|
let tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
config.change_dir(tempdir.path(), &|| {
|
|
expect_ok(config, &["rustup", "override", "add", "nightly"]);
|
|
expect_ok(config, &["rustup", "override", "remove"]);
|
|
expect_err(config, &["rustc"], "no default toolchain configured");
|
|
});
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_override_with_default() {
|
|
setup(&|config| {
|
|
let tempdir = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
config.change_dir(tempdir.path(), &|| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "override", "add", "beta"]);
|
|
expect_ok(config, &["rustup", "override", "remove"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
});
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_override_with_multiple_overrides() {
|
|
setup(&|config| {
|
|
let tempdir1 = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
let tempdir2 = tempfile::Builder::new().prefix("rustup").tempdir().unwrap();
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
config.change_dir(tempdir1.path(), &|| {
|
|
expect_ok(config, &["rustup", "override", "add", "beta"]);
|
|
});
|
|
config.change_dir(tempdir2.path(), &|| {
|
|
expect_ok(config, &["rustup", "override", "add", "stable"]);
|
|
});
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
config.change_dir(tempdir1.path(), &|| {
|
|
expect_ok(config, &["rustup", "override", "remove"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
});
|
|
config.change_dir(tempdir2.path(), &|| {
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-stable-1.1.0");
|
|
});
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn no_update_on_channel_when_date_has_not_changed() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_stdout_ok(
|
|
config,
|
|
&["rustup", "update", "nightly", "--no-self-update"],
|
|
"unchanged",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn update_on_channel_when_date_has_changed() {
|
|
clitools::setup(Scenario::ArchivesV2, &|config| {
|
|
set_current_dist_date(config, "2015-01-01");
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-1");
|
|
set_current_dist_date(config, "2015-01-02");
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn run_command() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_ok(config, &["rustup", "default", "beta"]);
|
|
expect_stdout_ok(
|
|
config,
|
|
&["rustup", "run", "nightly", "rustc", "--version"],
|
|
"hash-nightly-2",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_toolchain_then_add_again() {
|
|
// Issue brson/multirust #53
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "beta"]);
|
|
expect_ok(config, &["rustup", "toolchain", "remove", "beta"]);
|
|
expect_ok(config, &["rustup", "update", "beta", "--no-self-update"]);
|
|
expect_ok(config, &["rustc", "--version"]);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn upgrade_v1_to_v2() {
|
|
clitools::setup(Scenario::Full, &|config| {
|
|
set_current_dist_date(config, "2015-01-01");
|
|
// Delete the v2 manifest so the first day we install from the v1s
|
|
fs::remove_file(config.distdir.join("dist/channel-rust-nightly.toml.sha256")).unwrap();
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-1");
|
|
set_current_dist_date(config, "2015-01-02");
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "hash-nightly-2");
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn upgrade_v2_to_v1() {
|
|
clitools::setup(Scenario::Full, &|config| {
|
|
set_current_dist_date(config, "2015-01-01");
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
set_current_dist_date(config, "2015-01-02");
|
|
fs::remove_file(config.distdir.join("dist/channel-rust-nightly.toml.sha256")).unwrap();
|
|
expect_err(
|
|
config,
|
|
&["rustup", "update", "nightly"],
|
|
"the server unexpectedly provided an obsolete version of the distribution manifest",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn list_targets_no_toolchain() {
|
|
setup(&|config| {
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "list", "--toolchain=nightly"],
|
|
for_host!("toolchain 'nightly-{0}' is not installed"),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn list_targets_v1_toolchain() {
|
|
clitools::setup(Scenario::SimpleV1, &|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "list", "--toolchain=nightly"],
|
|
for_host!("toolchain 'nightly-{0}' does not support components"),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn list_targets_custom_toolchain() {
|
|
setup(&|config| {
|
|
let path = config.customdir.join("custom-1");
|
|
let path = path.to_string_lossy();
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "toolchain", "link", "default-from-path", &path],
|
|
);
|
|
expect_ok(config, &["rustup", "default", "default-from-path"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "list"],
|
|
"toolchain 'default-from-path' does not support components",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn list_targets() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_stdout_ok(config, &["rustup", "target", "list"], clitools::CROSS_ARCH1);
|
|
expect_stdout_ok(config, &["rustup", "target", "list"], clitools::CROSS_ARCH2);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn list_installed_targets() {
|
|
setup(&|config| {
|
|
let trip = this_host_triple();
|
|
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_stdout_ok(config, &["rustup", "target", "list", "--installed"], &trip);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_target1() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "target", "add", clitools::CROSS_ARCH1]);
|
|
let path = format!(
|
|
"toolchains/nightly-{}/lib/rustlib/{}/lib/libstd.rlib",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH1
|
|
);
|
|
assert!(config.rustupdir.join(path).exists());
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_target2() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "target", "add", clitools::CROSS_ARCH2]);
|
|
let path = format!(
|
|
"toolchains/nightly-{}/lib/rustlib/{}/lib/libstd.rlib",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH2
|
|
);
|
|
assert!(config.rustupdir.join(path).exists());
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_all_targets() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "target", "add", "all"]);
|
|
let path = format!(
|
|
"toolchains/nightly-{}/lib/rustlib/{}/lib/libstd.rlib",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH1
|
|
);
|
|
assert!(config.rustupdir.join(path).exists());
|
|
let path = format!(
|
|
"toolchains/nightly-{}/lib/rustlib/{}/lib/libstd.rlib",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH2
|
|
);
|
|
assert!(config.rustupdir.join(path).exists());
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_all_targets_fail() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_err(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"target",
|
|
"add",
|
|
clitools::CROSS_ARCH1,
|
|
"all",
|
|
clitools::CROSS_ARCH2,
|
|
],
|
|
&format!(
|
|
"`rustup target add {} all {}` includes `all`",
|
|
clitools::CROSS_ARCH1,
|
|
clitools::CROSS_ARCH2
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_target_no_toolchain() {
|
|
setup(&|config| {
|
|
expect_err(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"target",
|
|
"add",
|
|
clitools::CROSS_ARCH1,
|
|
"--toolchain=nightly",
|
|
],
|
|
for_host!("toolchain 'nightly-{0}' is not installed"),
|
|
);
|
|
});
|
|
}
|
|
#[test]
|
|
fn add_target_bogus() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "add", "bogus"],
|
|
"does not contain component 'rust-std' for target 'bogus'",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_target_v1_toolchain() {
|
|
clitools::setup(Scenario::SimpleV1, &|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_err(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"target",
|
|
"add",
|
|
clitools::CROSS_ARCH1,
|
|
"--toolchain=nightly",
|
|
],
|
|
for_host!("toolchain 'nightly-{0}' does not support components"),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_target_custom_toolchain() {
|
|
setup(&|config| {
|
|
let path = config.customdir.join("custom-1");
|
|
let path = path.to_string_lossy();
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "toolchain", "link", "default-from-path", &path],
|
|
);
|
|
expect_ok(config, &["rustup", "default", "default-from-path"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "add", clitools::CROSS_ARCH1],
|
|
"toolchain 'default-from-path' does not support components",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_target_again() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "target", "add", clitools::CROSS_ARCH1]);
|
|
expect_stderr_ok(
|
|
config,
|
|
&["rustup", "target", "add", clitools::CROSS_ARCH1],
|
|
&format!(
|
|
"component 'rust-std' for target '{}' is up to date",
|
|
clitools::CROSS_ARCH1
|
|
),
|
|
);
|
|
let path = format!(
|
|
"toolchains/nightly-{}/lib/rustlib/{}/lib/libstd.rlib",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH1
|
|
);
|
|
assert!(config.rustupdir.join(path).exists());
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_target_host() {
|
|
setup(&|config| {
|
|
let trip = TargetTriple::from_build();
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "target", "add", &trip.to_string()]);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "target", "add", clitools::CROSS_ARCH1]);
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "target", "remove", clitools::CROSS_ARCH1],
|
|
);
|
|
let path = format!(
|
|
"toolchains/nightly-{}/lib/rustlib/{}/lib/libstd.rlib",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH1
|
|
);
|
|
assert!(!config.rustupdir.join(path).exists());
|
|
let path = format!(
|
|
"toolchains/nightly-{}/lib/rustlib/{}/lib",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH1
|
|
);
|
|
assert!(!config.rustupdir.join(path).exists());
|
|
let path = format!(
|
|
"toolchains/nightly-{}/lib/rustlib/{}",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH1
|
|
);
|
|
assert!(!config.rustupdir.join(path).exists());
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target_not_installed() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "remove", clitools::CROSS_ARCH1],
|
|
&format!(
|
|
"toolchain 'nightly-{}' does not contain component 'rust-std' for target '{}'",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH1
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target_no_toolchain() {
|
|
setup(&|config| {
|
|
expect_err(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"target",
|
|
"remove",
|
|
clitools::CROSS_ARCH1,
|
|
"--toolchain=nightly",
|
|
],
|
|
for_host!("toolchain 'nightly-{0}' is not installed"),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target_bogus() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "remove", "bogus"],
|
|
"does not contain component 'rust-std' for target 'bogus'",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target_v1_toolchain() {
|
|
clitools::setup(Scenario::SimpleV1, &|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_err(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"target",
|
|
"remove",
|
|
clitools::CROSS_ARCH1,
|
|
"--toolchain=nightly",
|
|
],
|
|
for_host!("toolchain 'nightly-{0}' does not support components"),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target_custom_toolchain() {
|
|
setup(&|config| {
|
|
let path = config.customdir.join("custom-1");
|
|
let path = path.to_string_lossy();
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "toolchain", "link", "default-from-path", &path],
|
|
);
|
|
expect_ok(config, &["rustup", "default", "default-from-path"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "remove", clitools::CROSS_ARCH1],
|
|
"toolchain 'default-from-path' does not support components",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target_again() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "target", "add", clitools::CROSS_ARCH1]);
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "target", "remove", clitools::CROSS_ARCH1],
|
|
);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "target", "remove", clitools::CROSS_ARCH1],
|
|
&format!(
|
|
"toolchain 'nightly-{}' does not contain component 'rust-std' for target '{}'",
|
|
this_host_triple(),
|
|
clitools::CROSS_ARCH1
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target_host() {
|
|
setup(&|config| {
|
|
let trip = TargetTriple::from_build();
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(config, &["rustup", "target", "remove", &trip.to_string()]);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
// Issue #304
|
|
fn remove_target_missing_update_hash() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
|
|
let file_name = format!("nightly-{}", this_host_triple());
|
|
fs::remove_file(config.rustupdir.join("update-hashes").join(file_name)).unwrap();
|
|
|
|
expect_ok(config, &["rustup", "toolchain", "remove", "nightly"]);
|
|
});
|
|
}
|
|
|
|
// Issue #1777
|
|
#[test]
|
|
fn warn_about_and_remove_stray_hash() {
|
|
setup(&|config| {
|
|
let mut hash_path = config.rustupdir.join("update-hashes");
|
|
fs::create_dir_all(&hash_path).expect("Unable to make the update-hashes directory");
|
|
|
|
hash_path.push(for_host!("nightly-{}"));
|
|
|
|
let mut file = fs::File::create(&hash_path).expect("Unable to open update-hash file");
|
|
file.write_all(b"LEGITHASH")
|
|
.expect("Unable to write update-hash");
|
|
drop(file);
|
|
|
|
expect_stderr_ok(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"toolchain",
|
|
"install",
|
|
"nightly",
|
|
"--no-self-update",
|
|
],
|
|
&format!(
|
|
"removing stray hash found at '{}' in order to continue",
|
|
hash_path.display()
|
|
),
|
|
);
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_stdout_ok(config, &["rustc", "--version"], "1.3.0");
|
|
});
|
|
}
|
|
|
|
fn make_component_unavailable(config: &Config, name: &str, target: &TargetTriple) {
|
|
use crate::mock::dist::create_hash;
|
|
use rustup::dist::manifest::Manifest;
|
|
|
|
let manifest_path = config.distdir.join("dist/channel-rust-nightly.toml");
|
|
let manifest_str = fs::read_to_string(&manifest_path).unwrap();
|
|
let mut manifest = Manifest::parse(&manifest_str).unwrap();
|
|
{
|
|
let std_pkg = manifest.packages.get_mut(name).unwrap();
|
|
let target_pkg = std_pkg.targets.get_mut(target).unwrap();
|
|
target_pkg.bins = None;
|
|
}
|
|
let manifest_str = manifest.stringify();
|
|
rustup::utils::raw::write_file(&manifest_path, &manifest_str).unwrap();
|
|
|
|
// Have to update the hash too
|
|
let hash_path = manifest_path.with_extension("toml.sha256");
|
|
println!("{}", hash_path.display());
|
|
create_hash(&manifest_path, &hash_path);
|
|
}
|
|
|
|
#[test]
|
|
fn update_unavailable_std() {
|
|
setup(&|config| {
|
|
let trip = TargetTriple::from_build();
|
|
make_component_unavailable(config, "rust-std", &trip);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "update", "nightly", "--no-self-update"],
|
|
&format!(
|
|
"component 'rust-std' for target '{}' is unavailable for download for channel nightly",
|
|
trip,
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn update_unavailable_force() {
|
|
setup(&|config| {
|
|
let trip = TargetTriple::from_build();
|
|
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
|
|
expect_ok(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"component",
|
|
"add",
|
|
"rls",
|
|
"--toolchain",
|
|
"nightly",
|
|
],
|
|
);
|
|
make_component_unavailable(config, "rls-preview", &trip);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "update", "nightly", "--no-self-update"],
|
|
&format!(
|
|
"component 'rls' for target '{}' is unavailable for download for channel nightly",
|
|
trip,
|
|
),
|
|
);
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "update", "nightly", "--force", "--no-self-update"],
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_component_suggest_best_match() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "component", "add", "rsl"],
|
|
"did you mean 'rls'?",
|
|
);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "component", "add", "rsl-preview"],
|
|
"did you mean 'rls-preview'?",
|
|
);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "component", "add", "rustd"],
|
|
"did you mean 'rustc'?",
|
|
);
|
|
expect_not_stderr_ok(
|
|
config,
|
|
&["rustup", "component", "add", "potato"],
|
|
"did you mean",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_component_suggest_best_match() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_not_stderr_ok(
|
|
config,
|
|
&["rustup", "component", "remove", "rsl"],
|
|
"did you mean 'rls'?",
|
|
);
|
|
expect_ok(config, &["rustup", "component", "add", "rls"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "component", "remove", "rsl"],
|
|
"did you mean 'rls'?",
|
|
);
|
|
expect_ok(config, &["rustup", "component", "add", "rls-preview"]);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "component", "add", "rsl-preview"],
|
|
"did you mean 'rls-preview'?",
|
|
);
|
|
expect_err(
|
|
config,
|
|
&["rustup", "component", "remove", "rustd"],
|
|
"did you mean 'rustc'?",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn add_target_suggest_best_match() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_err(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"target",
|
|
"add",
|
|
&format!("{}a", clitools::CROSS_ARCH1)[..],
|
|
],
|
|
&format!("did you mean '{}'", clitools::CROSS_ARCH1),
|
|
);
|
|
expect_not_stderr_ok(
|
|
config,
|
|
&["rustup", "target", "add", "potato"],
|
|
"did you mean",
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn remove_target_suggest_best_match() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_not_stderr_ok(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"target",
|
|
"remove",
|
|
&format!("{}a", clitools::CROSS_ARCH1)[..],
|
|
],
|
|
&format!("did you mean '{}'", clitools::CROSS_ARCH1),
|
|
);
|
|
expect_ok(config, &["rustup", "target", "add", clitools::CROSS_ARCH1]);
|
|
expect_err(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"target",
|
|
"remove",
|
|
&format!("{}a", clitools::CROSS_ARCH1)[..],
|
|
],
|
|
&format!("did you mean '{}'", clitools::CROSS_ARCH1),
|
|
);
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn target_list_ignores_unavailable_targets() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
let target_list = &["rustup", "target", "list"];
|
|
expect_stdout_ok(config, target_list, clitools::CROSS_ARCH1);
|
|
let trip = TargetTriple::new(clitools::CROSS_ARCH1);
|
|
make_component_unavailable(config, "rust-std", &trip);
|
|
expect_ok(
|
|
config,
|
|
&["rustup", "update", "nightly", "--force", "--no-self-update"],
|
|
);
|
|
expect_not_stdout_ok(config, target_list, clitools::CROSS_ARCH1);
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn install_with_component_and_target() {
|
|
setup(&|config| {
|
|
expect_ok(config, &["rustup", "default", "nightly"]);
|
|
expect_ok(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"toolchain",
|
|
"install",
|
|
"nightly",
|
|
"-c",
|
|
"rls",
|
|
"-t",
|
|
clitools::CROSS_ARCH1,
|
|
"--no-self-update",
|
|
],
|
|
);
|
|
expect_stdout_ok(
|
|
config,
|
|
&["rustup", "component", "list"],
|
|
&format!("rls-{} (installed)", this_host_triple()),
|
|
);
|
|
expect_stdout_ok(
|
|
config,
|
|
&["rustup", "target", "list"],
|
|
&format!("{} (installed)", clitools::CROSS_ARCH1),
|
|
);
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_complete_profile_skips_missing_when_forced() {
|
|
setup_complex(&|config| {
|
|
set_current_dist_date(config, "2015-01-01");
|
|
|
|
expect_ok(config, &["rustup", "set", "profile", "complete"]);
|
|
// First try and install without force
|
|
expect_err(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"toolchain",
|
|
"install",
|
|
"nightly",
|
|
"--no-self-update",
|
|
],
|
|
for_host!("error: component 'rls' for target '{}' is unavailable for download for channel nightly")
|
|
);
|
|
// Now try and force
|
|
expect_stderr_ok(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"toolchain",
|
|
"install",
|
|
"--force",
|
|
"nightly",
|
|
"--no-self-update",
|
|
],
|
|
for_host!("warning: Force-skipping unavailable component 'rls-{}'"),
|
|
);
|
|
|
|
// Ensure that the skipped component (rls) is not installed
|
|
expect_not_stdout_ok(
|
|
config,
|
|
&["rustup", "component", "list"],
|
|
for_host!("rls-{} (installed)"),
|
|
);
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn run_with_install_flag_against_unavailable_component() {
|
|
setup(&|config| {
|
|
let trip = TargetTriple::from_build();
|
|
make_component_unavailable(config, "rust-std", &trip);
|
|
expect_ok_ex(
|
|
config,
|
|
&[
|
|
"rustup",
|
|
"run",
|
|
"--install",
|
|
"nightly",
|
|
"rustc",
|
|
"--version",
|
|
],
|
|
"1.3.0 (hash-nightly-2)
|
|
",
|
|
for_host!(
|
|
r"info: syncing channel updates for 'nightly-{0}'
|
|
info: latest update on 2015-01-02, rust version 1.3.0 (hash-nightly-2)
|
|
warning: Force-skipping unavailable component 'rust-std-{0}'
|
|
info: downloading component 'cargo'
|
|
info: downloading component 'rust-docs'
|
|
info: downloading component 'rustc'
|
|
info: installing component 'cargo'
|
|
info: installing component 'rust-docs'
|
|
info: installing component 'rustc'
|
|
"
|
|
),
|
|
);
|
|
});
|
|
}
|