700 lines
25 KiB
Rust
700 lines
25 KiB
Rust
use super::*;
|
|
use crate::config::{Config, DryRun, TargetSelection};
|
|
use crate::doc::DocumentationFormat;
|
|
use std::thread;
|
|
|
|
fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
|
|
configure_with_args(&[cmd.to_owned()], host, target)
|
|
}
|
|
|
|
fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config {
|
|
let mut config = Config::parse(cmd);
|
|
// don't save toolstates
|
|
config.save_toolstates = None;
|
|
config.dry_run = DryRun::SelfCheck;
|
|
|
|
// Ignore most submodules, since we don't need them for a dry run.
|
|
// But make sure to check out the `doc` and `rust-analyzer` submodules, since some steps need them
|
|
// just to know which commands to run.
|
|
let submodule_build = Build::new(Config {
|
|
// don't include LLVM, so CI doesn't require ninja/cmake to be installed
|
|
rust_codegen_backends: vec![],
|
|
..Config::parse(&["check".to_owned()])
|
|
});
|
|
submodule_build.update_submodule(Path::new("src/doc/book"));
|
|
submodule_build.update_submodule(Path::new("src/tools/rust-analyzer"));
|
|
config.submodules = Some(false);
|
|
|
|
config.ninja_in_file = false;
|
|
// try to avoid spurious failures in dist where we create/delete each others file
|
|
// HACK: rather than pull in `tempdir`, use the one that cargo has conveniently created for us
|
|
let dir = Path::new(env!("OUT_DIR"))
|
|
.join("tmp-rustbuild-tests")
|
|
.join(&thread::current().name().unwrap_or("unknown").replace(":", "-"));
|
|
t!(fs::create_dir_all(&dir));
|
|
config.out = dir;
|
|
config.build = TargetSelection::from_user("A");
|
|
config.hosts = host.iter().map(|s| TargetSelection::from_user(s)).collect();
|
|
config.targets = target.iter().map(|s| TargetSelection::from_user(s)).collect();
|
|
config
|
|
}
|
|
|
|
fn first<A, B>(v: Vec<(A, B)>) -> Vec<A> {
|
|
v.into_iter().map(|(a, _)| a).collect::<Vec<_>>()
|
|
}
|
|
|
|
fn run_build(paths: &[PathBuf], config: Config) -> Cache {
|
|
let kind = config.cmd.kind();
|
|
let build = Build::new(config);
|
|
let builder = Builder::new(&build);
|
|
builder.run_step_descriptions(&Builder::get_step_descriptions(kind), paths);
|
|
builder.cache
|
|
}
|
|
|
|
fn check_cli<const N: usize>(paths: [&str; N]) {
|
|
run_build(
|
|
&paths.map(PathBuf::from),
|
|
configure_with_args(&paths.map(String::from), &["A"], &["A"]),
|
|
);
|
|
}
|
|
|
|
macro_rules! std {
|
|
($host:ident => $target:ident, stage = $stage:literal) => {
|
|
compile::Std::new(
|
|
Compiler { host: TargetSelection::from_user(stringify!($host)), stage: $stage },
|
|
TargetSelection::from_user(stringify!($target)),
|
|
)
|
|
};
|
|
}
|
|
|
|
macro_rules! doc_std {
|
|
($host:ident => $target:ident, stage = $stage:literal) => {{
|
|
let config = configure("doc", &["A"], &["A"]);
|
|
let build = Build::new(config);
|
|
let builder = Builder::new(&build);
|
|
doc::Std::new(
|
|
$stage,
|
|
TargetSelection::from_user(stringify!($target)),
|
|
&builder,
|
|
DocumentationFormat::HTML,
|
|
)
|
|
}};
|
|
}
|
|
|
|
macro_rules! rustc {
|
|
($host:ident => $target:ident, stage = $stage:literal) => {
|
|
compile::Rustc::new(
|
|
Compiler { host: TargetSelection::from_user(stringify!($host)), stage: $stage },
|
|
TargetSelection::from_user(stringify!($target)),
|
|
)
|
|
};
|
|
}
|
|
|
|
#[test]
|
|
fn test_valid() {
|
|
// make sure multi suite paths are accepted
|
|
check_cli(["test", "tests/ui/attr-start.rs", "tests/ui/attr-shebang.rs"]);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic]
|
|
fn test_invalid() {
|
|
// make sure that invalid paths are caught, even when combined with valid paths
|
|
check_cli(["test", "library/std", "x"]);
|
|
}
|
|
|
|
#[test]
|
|
fn test_intersection() {
|
|
let set = |paths: &[&str]| {
|
|
PathSet::Set(paths.into_iter().map(|p| TaskPath { path: p.into(), kind: None }).collect())
|
|
};
|
|
let library_set = set(&["library/core", "library/alloc", "library/std"]);
|
|
let mut command_paths =
|
|
vec![Path::new("library/core"), Path::new("library/alloc"), Path::new("library/stdarch")];
|
|
let subset = library_set.intersection_removing_matches(&mut command_paths, Kind::Build);
|
|
assert_eq!(subset, set(&["library/core", "library/alloc"]),);
|
|
assert_eq!(command_paths, vec![Path::new("library/stdarch")]);
|
|
}
|
|
|
|
#[test]
|
|
fn test_exclude() {
|
|
let mut config = configure("test", &["A"], &["A"]);
|
|
config.skip = vec!["src/tools/tidy".into()];
|
|
let cache = run_build(&[], config);
|
|
|
|
// Ensure we have really excluded tidy
|
|
assert!(!cache.contains::<test::Tidy>());
|
|
|
|
// Ensure other tests are not affected.
|
|
assert!(cache.contains::<test::RustdocUi>());
|
|
}
|
|
|
|
#[test]
|
|
fn test_exclude_kind() {
|
|
let path = PathBuf::from("compiler/rustc_data_structures");
|
|
|
|
let mut config = configure("test", &["A"], &["A"]);
|
|
// Ensure our test is valid, and `test::Rustc` would be run without the exclude.
|
|
assert!(run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
|
|
// Ensure tests for rustc are skipped.
|
|
config.skip = vec![path.clone()];
|
|
assert!(!run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
|
|
// Ensure builds for rustc are not skipped.
|
|
assert!(run_build(&[], config).contains::<compile::Rustc>());
|
|
}
|
|
|
|
/// Ensure that if someone passes both a single crate and `library`, all library crates get built.
|
|
#[test]
|
|
fn alias_and_path_for_library() {
|
|
let mut cache =
|
|
run_build(&["library".into(), "core".into()], configure("build", &["A"], &["A"]));
|
|
assert_eq!(
|
|
first(cache.all::<compile::Std>()),
|
|
&[std!(A => A, stage = 0), std!(A => A, stage = 1)]
|
|
);
|
|
|
|
let mut cache = run_build(&["library".into(), "core".into()], configure("doc", &["A"], &["A"]));
|
|
assert_eq!(first(cache.all::<doc::Std>()), &[doc_std!(A => A, stage = 0)]);
|
|
}
|
|
|
|
#[test]
|
|
fn test_beta_rev_parsing() {
|
|
use crate::extract_beta_rev;
|
|
|
|
// single digit revision
|
|
assert_eq!(extract_beta_rev("1.99.9-beta.7 (xxxxxx)"), Some("7".to_string()));
|
|
// multiple digits
|
|
assert_eq!(extract_beta_rev("1.99.9-beta.777 (xxxxxx)"), Some("777".to_string()));
|
|
// nightly channel (no beta revision)
|
|
assert_eq!(extract_beta_rev("1.99.9-nightly (xxxxxx)"), None);
|
|
// stable channel (no beta revision)
|
|
assert_eq!(extract_beta_rev("1.99.9 (xxxxxxx)"), None);
|
|
// invalid string
|
|
assert_eq!(extract_beta_rev("invalid"), None);
|
|
}
|
|
|
|
mod defaults {
|
|
use super::{configure, first, run_build};
|
|
use crate::builder::*;
|
|
use crate::Config;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[test]
|
|
fn build_default() {
|
|
let mut cache = run_build(&[], configure("build", &["A"], &["A"]));
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
assert_eq!(
|
|
first(cache.all::<compile::Std>()),
|
|
&[std!(A => A, stage = 0), std!(A => A, stage = 1),]
|
|
);
|
|
assert!(!cache.all::<compile::Assemble>().is_empty());
|
|
// Make sure rustdoc is only built once.
|
|
assert_eq!(
|
|
first(cache.all::<tool::Rustdoc>()),
|
|
// Recall that rustdoc stages are off-by-one
|
|
// - this is the compiler it's _linked_ to, not built with.
|
|
&[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }],
|
|
);
|
|
assert_eq!(first(cache.all::<compile::Rustc>()), &[rustc!(A => A, stage = 0)],);
|
|
}
|
|
|
|
#[test]
|
|
fn build_stage_0() {
|
|
let config = Config { stage: 0, ..configure("build", &["A"], &["A"]) };
|
|
let mut cache = run_build(&[], config);
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
assert_eq!(first(cache.all::<compile::Std>()), &[std!(A => A, stage = 0)]);
|
|
assert!(!cache.all::<compile::Assemble>().is_empty());
|
|
assert_eq!(
|
|
first(cache.all::<tool::Rustdoc>()),
|
|
// This is the beta rustdoc.
|
|
// Add an assert here to make sure this is the only rustdoc built.
|
|
&[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }],
|
|
);
|
|
assert!(cache.all::<compile::Rustc>().is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn build_cross_compile() {
|
|
let config = Config { stage: 1, ..configure("build", &["A", "B"], &["A", "B"]) };
|
|
let mut cache = run_build(&[], config);
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
let b = TargetSelection::from_user("B");
|
|
|
|
// Ideally, this build wouldn't actually have `target: a`
|
|
// rustdoc/rustcc/std here (the user only requested a host=B build, so
|
|
// there's not really a need for us to build for target A in this case
|
|
// (since we're producing stage 1 libraries/binaries). But currently
|
|
// rustbuild is just a bit buggy here; this should be fixed though.
|
|
assert_eq!(
|
|
first(cache.all::<compile::Std>()),
|
|
&[
|
|
std!(A => A, stage = 0),
|
|
std!(A => A, stage = 1),
|
|
std!(A => B, stage = 0),
|
|
std!(A => B, stage = 1),
|
|
]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<compile::Assemble>()),
|
|
&[
|
|
compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
|
|
compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
|
|
compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<tool::Rustdoc>()),
|
|
&[
|
|
tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
|
|
tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } },
|
|
],
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<compile::Rustc>()),
|
|
&[rustc!(A => A, stage = 0), rustc!(A => B, stage = 0),]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn doc_default() {
|
|
let mut config = configure("doc", &["A"], &["A"]);
|
|
config.compiler_docs = true;
|
|
config.cmd = Subcommand::Doc { open: false, json: false };
|
|
let mut cache = run_build(&[], config);
|
|
let a = TargetSelection::from_user("A");
|
|
|
|
// error_index_generator uses stage 0 to share rustdoc artifacts with the
|
|
// rustdoc tool.
|
|
assert_eq!(first(cache.all::<doc::ErrorIndex>()), &[doc::ErrorIndex { target: a },]);
|
|
assert_eq!(
|
|
first(cache.all::<tool::ErrorIndex>()),
|
|
&[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }]
|
|
);
|
|
// docs should be built with the beta compiler, not with the stage0 artifacts.
|
|
// recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to,
|
|
// not the one it was built by.
|
|
assert_eq!(
|
|
first(cache.all::<tool::Rustdoc>()),
|
|
&[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },]
|
|
);
|
|
}
|
|
}
|
|
|
|
mod dist {
|
|
use super::{first, run_build, Config};
|
|
use crate::builder::*;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
fn configure(host: &[&str], target: &[&str]) -> Config {
|
|
Config { stage: 2, ..super::configure("dist", host, target) }
|
|
}
|
|
|
|
#[test]
|
|
fn dist_baseline() {
|
|
let mut cache = run_build(&[], configure(&["A"], &["A"]));
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
|
|
assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a },]);
|
|
assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Rustc>()),
|
|
&[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Std>()),
|
|
&[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },]
|
|
);
|
|
assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
|
|
// Make sure rustdoc is only built once.
|
|
assert_eq!(
|
|
first(cache.all::<tool::Rustdoc>()),
|
|
&[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dist_with_targets() {
|
|
let mut cache = run_build(&[], configure(&["A"], &["A", "B"]));
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
let b = TargetSelection::from_user("B");
|
|
|
|
assert_eq!(
|
|
first(cache.all::<dist::Docs>()),
|
|
&[dist::Docs { host: a }, dist::Docs { host: b },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Mingw>()),
|
|
&[dist::Mingw { host: a }, dist::Mingw { host: b },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Rustc>()),
|
|
&[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Std>()),
|
|
&[
|
|
dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
|
|
dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
|
|
]
|
|
);
|
|
assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
|
|
}
|
|
|
|
#[test]
|
|
fn dist_with_hosts() {
|
|
let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B"]));
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
let b = TargetSelection::from_user("B");
|
|
|
|
assert_eq!(
|
|
first(cache.all::<dist::Docs>()),
|
|
&[dist::Docs { host: a }, dist::Docs { host: b },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Mingw>()),
|
|
&[dist::Mingw { host: a }, dist::Mingw { host: b },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Rustc>()),
|
|
&[
|
|
dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
|
|
dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Std>()),
|
|
&[
|
|
dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
|
|
dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<compile::Std>()),
|
|
&[
|
|
std!(A => A, stage = 0),
|
|
std!(A => A, stage = 1),
|
|
std!(A => A, stage = 2),
|
|
std!(A => B, stage = 1),
|
|
std!(A => B, stage = 2),
|
|
],
|
|
);
|
|
assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
|
|
}
|
|
|
|
#[test]
|
|
fn dist_only_cross_host() {
|
|
let b = TargetSelection::from_user("B");
|
|
let mut config = configure(&["A", "B"], &["A", "B"]);
|
|
config.docs = false;
|
|
config.extended = true;
|
|
config.hosts = vec![b];
|
|
let mut cache = run_build(&[], config);
|
|
|
|
assert_eq!(
|
|
first(cache.all::<dist::Rustc>()),
|
|
&[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<compile::Rustc>()),
|
|
&[rustc!(A => A, stage = 0), rustc!(A => B, stage = 1),]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dist_with_targets_and_hosts() {
|
|
let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B", "C"]));
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
let b = TargetSelection::from_user("B");
|
|
let c = TargetSelection::from_user("C");
|
|
|
|
assert_eq!(
|
|
first(cache.all::<dist::Docs>()),
|
|
&[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Mingw>()),
|
|
&[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Rustc>()),
|
|
&[
|
|
dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
|
|
dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Std>()),
|
|
&[
|
|
dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
|
|
dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
|
|
dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
|
|
]
|
|
);
|
|
assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
|
|
}
|
|
|
|
#[test]
|
|
fn dist_with_empty_host() {
|
|
let config = configure(&[], &["C"]);
|
|
let mut cache = run_build(&[], config);
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
let c = TargetSelection::from_user("C");
|
|
|
|
assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: c },]);
|
|
assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: c },]);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Std>()),
|
|
&[dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dist_with_same_targets_and_hosts() {
|
|
let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B"]));
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
let b = TargetSelection::from_user("B");
|
|
|
|
assert_eq!(
|
|
first(cache.all::<dist::Docs>()),
|
|
&[dist::Docs { host: a }, dist::Docs { host: b },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Mingw>()),
|
|
&[dist::Mingw { host: a }, dist::Mingw { host: b },]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Rustc>()),
|
|
&[
|
|
dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
|
|
dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<dist::Std>()),
|
|
&[
|
|
dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
|
|
dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
|
|
]
|
|
);
|
|
assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
|
|
assert_eq!(
|
|
first(cache.all::<compile::Std>()),
|
|
&[
|
|
std!(A => A, stage = 0),
|
|
std!(A => A, stage = 1),
|
|
std!(A => A, stage = 2),
|
|
std!(A => B, stage = 1),
|
|
std!(A => B, stage = 2),
|
|
]
|
|
);
|
|
assert_eq!(
|
|
first(cache.all::<compile::Assemble>()),
|
|
&[
|
|
compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
|
|
compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
|
|
compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
|
|
compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } },
|
|
]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn build_all() {
|
|
let build = Build::new(configure(&["A", "B"], &["A", "B", "C"]));
|
|
let mut builder = Builder::new(&build);
|
|
builder.run_step_descriptions(
|
|
&Builder::get_step_descriptions(Kind::Build),
|
|
&["compiler/rustc".into(), "library".into()],
|
|
);
|
|
|
|
assert_eq!(
|
|
first(builder.cache.all::<compile::Std>()),
|
|
&[
|
|
std!(A => A, stage = 0),
|
|
std!(A => A, stage = 1),
|
|
std!(A => A, stage = 2),
|
|
std!(A => B, stage = 1),
|
|
std!(A => B, stage = 2),
|
|
std!(A => C, stage = 2),
|
|
]
|
|
);
|
|
assert_eq!(builder.cache.all::<compile::Assemble>().len(), 5);
|
|
assert_eq!(
|
|
first(builder.cache.all::<compile::Rustc>()),
|
|
&[
|
|
rustc!(A => A, stage = 0),
|
|
rustc!(A => A, stage = 1),
|
|
rustc!(A => A, stage = 2),
|
|
rustc!(A => B, stage = 1),
|
|
rustc!(A => B, stage = 2),
|
|
]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn build_with_empty_host() {
|
|
let config = configure(&[], &["C"]);
|
|
let build = Build::new(config);
|
|
let mut builder = Builder::new(&build);
|
|
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
|
|
|
|
let a = TargetSelection::from_user("A");
|
|
|
|
assert_eq!(
|
|
first(builder.cache.all::<compile::Std>()),
|
|
&[std!(A => A, stage = 0), std!(A => A, stage = 1), std!(A => C, stage = 2),]
|
|
);
|
|
assert_eq!(
|
|
first(builder.cache.all::<compile::Assemble>()),
|
|
&[
|
|
compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
|
|
compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
|
|
compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
first(builder.cache.all::<compile::Rustc>()),
|
|
&[rustc!(A => A, stage = 0), rustc!(A => A, stage = 1),]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_with_no_doc_stage0() {
|
|
let mut config = configure(&["A"], &["A"]);
|
|
config.stage = 0;
|
|
config.paths = vec!["library/std".into()];
|
|
config.cmd = Subcommand::Test {
|
|
test_args: vec![],
|
|
rustc_args: vec![],
|
|
no_fail_fast: false,
|
|
no_doc: true,
|
|
doc: false,
|
|
bless: false,
|
|
force_rerun: false,
|
|
compare_mode: None,
|
|
rustfix_coverage: false,
|
|
pass: None,
|
|
run: None,
|
|
only_modified: false,
|
|
skip: vec![],
|
|
};
|
|
|
|
let build = Build::new(config);
|
|
let mut builder = Builder::new(&build);
|
|
|
|
let host = TargetSelection::from_user("A");
|
|
|
|
builder.run_step_descriptions(
|
|
&[StepDescription::from::<test::Crate>(Kind::Test)],
|
|
&["library/std".into()],
|
|
);
|
|
|
|
// Ensure we don't build any compiler artifacts.
|
|
assert!(!builder.cache.contains::<compile::Rustc>());
|
|
assert_eq!(
|
|
first(builder.cache.all::<test::Crate>()),
|
|
&[test::Crate {
|
|
compiler: Compiler { host, stage: 0 },
|
|
target: host,
|
|
mode: Mode::Std,
|
|
crates: vec![INTERNER.intern_str("std")],
|
|
},]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn doc_ci() {
|
|
let mut config = configure(&["A"], &["A"]);
|
|
config.compiler_docs = true;
|
|
config.cmd = Subcommand::Doc { open: false, json: false };
|
|
let build = Build::new(config);
|
|
let mut builder = Builder::new(&build);
|
|
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]);
|
|
let a = TargetSelection::from_user("A");
|
|
|
|
// error_index_generator uses stage 1 to share rustdoc artifacts with the
|
|
// rustdoc tool.
|
|
assert_eq!(
|
|
first(builder.cache.all::<doc::ErrorIndex>()),
|
|
&[doc::ErrorIndex { target: a },]
|
|
);
|
|
assert_eq!(
|
|
first(builder.cache.all::<tool::ErrorIndex>()),
|
|
&[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
|
|
);
|
|
// This is actually stage 1, but Rustdoc::run swaps out the compiler with
|
|
// stage minus 1 if --stage is not 0. Very confusing!
|
|
assert_eq!(
|
|
first(builder.cache.all::<tool::Rustdoc>()),
|
|
&[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_docs() {
|
|
// Behavior of `x.py test` doing various documentation tests.
|
|
let mut config = configure(&["A"], &["A"]);
|
|
config.cmd = Subcommand::Test {
|
|
test_args: vec![],
|
|
rustc_args: vec![],
|
|
no_fail_fast: false,
|
|
doc: true,
|
|
no_doc: false,
|
|
skip: vec![],
|
|
bless: false,
|
|
force_rerun: false,
|
|
compare_mode: None,
|
|
rustfix_coverage: false,
|
|
pass: None,
|
|
run: None,
|
|
only_modified: false,
|
|
};
|
|
// Make sure rustfmt binary not being found isn't an error.
|
|
config.channel = "beta".to_string();
|
|
let build = Build::new(config);
|
|
let mut builder = Builder::new(&build);
|
|
|
|
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]);
|
|
let a = TargetSelection::from_user("A");
|
|
|
|
// error_index_generator uses stage 1 to share rustdoc artifacts with the
|
|
// rustdoc tool.
|
|
assert_eq!(
|
|
first(builder.cache.all::<doc::ErrorIndex>()),
|
|
&[doc::ErrorIndex { target: a },]
|
|
);
|
|
assert_eq!(
|
|
first(builder.cache.all::<tool::ErrorIndex>()),
|
|
&[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
|
|
);
|
|
// Unfortunately rustdoc is built twice. Once from stage1 for compiletest
|
|
// (and other things), and once from stage0 for std crates. Ideally it
|
|
// would only be built once. If someone wants to fix this, it might be
|
|
// worth investigating if it would be possible to test std from stage1.
|
|
// Note that the stages here are +1 than what they actually are because
|
|
// Rustdoc::run swaps out the compiler with stage minus 1 if --stage is
|
|
// not 0.
|
|
//
|
|
// The stage 0 copy is the one downloaded for bootstrapping. It is
|
|
// (currently) needed to run "cargo test" on the linkchecker, and
|
|
// should be relatively "free".
|
|
assert_eq!(
|
|
first(builder.cache.all::<tool::Rustdoc>()),
|
|
&[
|
|
tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },
|
|
tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
|
|
tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },
|
|
]
|
|
);
|
|
}
|
|
}
|