use super::*; use crate::config::Config; use std::thread; use pretty_assertions::assert_eq; fn configure(host: &[&str], target: &[&str]) -> Config { let mut config = Config::default_opts(); // don't save toolstates config.save_toolstates = None; config.skip_only_host_steps = false; config.dry_run = true; // try to avoid spurious failures in dist where we create/delete each others file let dir = config.out.join("tmp-rustbuild-tests").join( &thread::current() .name() .unwrap_or("unknown") .replace(":", "-"), ); t!(fs::create_dir_all(&dir)); config.out = dir; config.build = INTERNER.intern_str("A"); config.hosts = vec![config.build] .clone() .into_iter() .chain(host.iter().map(|s| INTERNER.intern_str(s))) .collect::>(); config.targets = config .hosts .clone() .into_iter() .chain(target.iter().map(|s| INTERNER.intern_str(s))) .collect::>(); config } fn first(v: Vec<(A, B)>) -> Vec { v.into_iter().map(|(a, _)| a).collect::>() } #[test] fn dist_baseline() { let build = Build::new(configure(&[], &[])); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); let a = INTERNER.intern_str("A"); assert_eq!( first(builder.cache.all::()), &[dist::Docs { host: a },] ); assert_eq!( first(builder.cache.all::()), &[dist::Mingw { host: a },] ); assert_eq!( first(builder.cache.all::()), &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] ); assert_eq!( first(builder.cache.all::()), &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a, },] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); } #[test] fn dist_with_targets() { let build = Build::new(configure(&[], &["B"])); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); let a = INTERNER.intern_str("A"); let b = INTERNER.intern_str("B"); assert_eq!( first(builder.cache.all::()), &[ dist::Docs { host: a }, dist::Docs { host: b }, ] ); assert_eq!( first(builder.cache.all::()), &[dist::Mingw { host: a }, dist::Mingw { host: b },] ); assert_eq!( first(builder.cache.all::()), &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] ); assert_eq!( first(builder.cache.all::()), &[ dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a, }, dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b, }, ] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); } #[test] fn dist_with_hosts() { let build = Build::new(configure(&["B"], &[])); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); let a = INTERNER.intern_str("A"); let b = INTERNER.intern_str("B"); assert_eq!( first(builder.cache.all::()), &[ dist::Docs { host: a }, dist::Docs { host: b }, ] ); assert_eq!( first(builder.cache.all::()), &[dist::Mingw { host: a }, dist::Mingw { host: b },] ); assert_eq!( first(builder.cache.all::()), &[ dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( first(builder.cache.all::()), &[ dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a, }, dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b, }, ] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); } #[test] fn dist_only_cross_host() { let a = INTERNER.intern_str("A"); let b = INTERNER.intern_str("B"); let mut build = Build::new(configure(&["B"], &[])); build.config.docs = false; build.config.extended = true; build.hosts = vec![b]; let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); assert_eq!( first(builder.cache.all::()), &[ dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( first(builder.cache.all::()), &[ compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a, }, compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b, }, ] ); } #[test] fn dist_with_targets_and_hosts() { let build = Build::new(configure(&["B"], &["C"])); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); let a = INTERNER.intern_str("A"); let b = INTERNER.intern_str("B"); let c = INTERNER.intern_str("C"); assert_eq!( first(builder.cache.all::()), &[ dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c }, ] ); assert_eq!( first(builder.cache.all::()), &[ dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c }, ] ); assert_eq!( first(builder.cache.all::()), &[ dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( first(builder.cache.all::()), &[ 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(builder.cache.all::()), &[dist::Src]); } #[test] fn dist_with_target_flag() { let mut config = configure(&["B"], &["C"]); config.skip_only_host_steps = true; // as-if --target=C was passed let build = Build::new(config); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); let a = INTERNER.intern_str("A"); let b = INTERNER.intern_str("B"); let c = INTERNER.intern_str("C"); assert_eq!( first(builder.cache.all::()), &[ dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c }, ] ); assert_eq!( first(builder.cache.all::()), &[ dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c }, ] ); assert_eq!(first(builder.cache.all::()), &[]); assert_eq!( first(builder.cache.all::()), &[ 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(builder.cache.all::()), &[]); } #[test] fn dist_with_same_targets_and_hosts() { let build = Build::new(configure(&["B"], &["B"])); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); let a = INTERNER.intern_str("A"); let b = INTERNER.intern_str("B"); assert_eq!( first(builder.cache.all::()), &[ dist::Docs { host: a }, dist::Docs { host: b }, ] ); assert_eq!( first(builder.cache.all::()), &[dist::Mingw { host: a }, dist::Mingw { host: b },] ); assert_eq!( first(builder.cache.all::()), &[ dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( first(builder.cache.all::()), &[ dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a, }, dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b, }, ] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); assert_eq!( first(builder.cache.all::()), &[ compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b, }, ] ); assert_eq!( first(builder.cache.all::()), &[ 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_default() { let build = Build::new(configure(&["B"], &["C"])); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); let a = INTERNER.intern_str("A"); let b = INTERNER.intern_str("B"); let c = INTERNER.intern_str("C"); assert_eq!( first(builder.cache.all::()), &[ compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a, }, compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b, }, compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b, }, compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b, }, compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c, }, compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c, }, ] ); assert!(!builder.cache.all::().is_empty()); assert_eq!( first(builder.cache.all::()), &[ compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a, }, compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a, }, compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a, }, compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: a, }, compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b, }, compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b, }, compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: b, }, ] ); } #[test] fn build_with_target_flag() { let mut config = configure(&["B"], &["C"]); config.skip_only_host_steps = true; let build = Build::new(config); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); let a = INTERNER.intern_str("A"); let b = INTERNER.intern_str("B"); let c = INTERNER.intern_str("C"); assert_eq!( first(builder.cache.all::()), &[ compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a, }, compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a, }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b, }, compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b, }, compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b, }, compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c, }, compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c, }, ] ); assert_eq!( first(builder.cache.all::()), &[ 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 }, }, ] ); assert_eq!( first(builder.cache.all::()), &[ compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a, }, compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a, }, compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b, }, ] ); } #[test] fn test_with_no_doc_stage0() { let mut config = configure(&[], &[]); config.stage = Some(0); config.cmd = Subcommand::Test { paths: vec!["src/libstd".into()], test_args: vec![], rustc_args: vec![], fail_fast: true, doc_tests: DocTests::No, bless: false, compare_mode: None, rustfix_coverage: false, pass: None, }; let build = Build::new(config); let mut builder = Builder::new(&build); let host = INTERNER.intern_str("A"); builder.run_step_descriptions( &[StepDescription::from::()], &["src/libstd".into()], ); // Ensure we don't build any compiler artifacts. assert!(!builder.cache.contains::()); assert_eq!( first(builder.cache.all::()), &[test::Crate { compiler: Compiler { host, stage: 0 }, target: host, mode: Mode::Std, test_kind: test::TestKind::Test, krate: INTERNER.intern_str("std"), },] ); } #[test] fn test_exclude() { let mut config = configure(&[], &[]); config.exclude = vec![ "src/tools/tidy".into(), ]; config.cmd = Subcommand::Test { paths: Vec::new(), test_args: Vec::new(), rustc_args: Vec::new(), fail_fast: true, doc_tests: DocTests::No, bless: false, compare_mode: None, rustfix_coverage: false, pass: None, }; let build = Build::new(config); let builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); // Ensure we have really excluded tidy assert!(!builder.cache.contains::()); // Ensure other tests are not affected. assert!(builder.cache.contains::()); }