|
| 1 | +use std::env::VarError; |
1 | 2 | use std::{panic, thread};
|
2 | 3 |
|
| 4 | +use build_helper::stage0_parser::parse_stage0_file; |
3 | 5 | use llvm::prebuilt_llvm_config;
|
4 | 6 |
|
5 | 7 | use super::*;
|
6 | 8 | use crate::Flags;
|
7 | 9 | use crate::core::build_steps::doc::DocumentationFormat;
|
8 | 10 | use crate::core::config::Config;
|
| 11 | +use crate::utils::tests::git::{GitCtx, git_test}; |
9 | 12 |
|
10 | 13 | static TEST_TRIPLE_1: &str = "i686-unknown-haiku";
|
11 | 14 | static TEST_TRIPLE_2: &str = "i686-unknown-hurd-gnu";
|
@@ -238,6 +241,125 @@ fn alias_and_path_for_library() {
|
238 | 241 | );
|
239 | 242 | }
|
240 | 243 |
|
| 244 | +#[test] |
| 245 | +fn ci_rustc_if_unchanged_invalidate_on_compiler_changes() { |
| 246 | + git_test(|ctx| { |
| 247 | + prepare_rustc_checkout(ctx); |
| 248 | + ctx.create_upstream_merge(&["compiler/bar"]); |
| 249 | + // This change should invalidate download-ci-rustc |
| 250 | + ctx.create_nonupstream_merge(&["compiler/foo"]); |
| 251 | + |
| 252 | + let config = parse_config_download_rustc_at(ctx.get_path(), "if-unchanged"); |
| 253 | + assert_eq!(config.download_rustc_commit, None); |
| 254 | + }); |
| 255 | +} |
| 256 | + |
| 257 | +#[test] |
| 258 | +fn ci_rustc_if_unchanged_invalidate_on_library_changes_in_ci() { |
| 259 | + git_test(|ctx| { |
| 260 | + prepare_rustc_checkout(ctx); |
| 261 | + ctx.create_upstream_merge(&["compiler/bar"]); |
| 262 | + // This change should invalidate download-ci-rustc |
| 263 | + ctx.create_nonupstream_merge(&["library/foo"]); |
| 264 | + |
| 265 | + with_mocked_ci(|| { |
| 266 | + let config = parse_config_download_rustc_at(ctx.get_path(), "if-unchanged"); |
| 267 | + assert_eq!(config.download_rustc_commit, None); |
| 268 | + }); |
| 269 | + }); |
| 270 | +} |
| 271 | + |
| 272 | +#[test] |
| 273 | +fn ci_rustc_if_unchanged_do_not_invalidate_on_library_changes_outside_ci() { |
| 274 | + git_test(|ctx| { |
| 275 | + prepare_rustc_checkout(ctx); |
| 276 | + let sha = ctx.create_upstream_merge(&["compiler/bar"]); |
| 277 | + // This change should not invalidate download-ci-rustc |
| 278 | + ctx.create_nonupstream_merge(&["library/foo"]); |
| 279 | + |
| 280 | + with_mocked_outside_ci(|| { |
| 281 | + let config = parse_config_download_rustc_at(ctx.get_path(), "if-unchanged"); |
| 282 | + assert_eq!(config.download_rustc_commit, Some(sha)); |
| 283 | + }); |
| 284 | + }); |
| 285 | +} |
| 286 | + |
| 287 | +#[test] |
| 288 | +fn ci_rustc_if_unchanged_do_not_invalidate_on_tool_changes() { |
| 289 | + git_test(|ctx| { |
| 290 | + prepare_rustc_checkout(ctx); |
| 291 | + let sha = ctx.create_upstream_merge(&["compiler/bar"]); |
| 292 | + // This change should not invalidate download-ci-rustc |
| 293 | + ctx.create_nonupstream_merge(&["src/tools/foo"]); |
| 294 | + |
| 295 | + let config = parse_config_download_rustc_at(ctx.get_path(), "if-unchanged"); |
| 296 | + assert_eq!(config.download_rustc_commit, Some(sha)); |
| 297 | + }); |
| 298 | +} |
| 299 | + |
| 300 | +/// Temporarily mocks the current environment to make it look like we're in CI. |
| 301 | +/// If we are actually in CI, nothing changes. |
| 302 | +fn with_mocked_ci<F, R>(func: F) -> R |
| 303 | +where |
| 304 | + F: FnOnce() -> R, |
| 305 | +{ |
| 306 | + if let Err(VarError::NotPresent) = std::env::var("GITHUB_ACTIONS") { |
| 307 | + // SAFETY: bootstrap tests are sequential |
| 308 | + unsafe { std::env::set_var("GITHUB_ACTIONS", "true") }; |
| 309 | + |
| 310 | + let ret = func(); |
| 311 | + |
| 312 | + // SAFETY: bootstrap tests are sequential |
| 313 | + unsafe { std::env::remove_var("GITHUB_ACTIONS") }; |
| 314 | + ret |
| 315 | + } else { |
| 316 | + func() |
| 317 | + } |
| 318 | +} |
| 319 | + |
| 320 | +/// Temporarily mocks the current environment to make it look like we're **NOT** in CI. |
| 321 | +/// If we are actually not in CI, nothing changes. |
| 322 | +fn with_mocked_outside_ci<F, R>(func: F) -> R |
| 323 | +where |
| 324 | + F: FnOnce() -> R, |
| 325 | +{ |
| 326 | + if let Ok(var) = std::env::var("GITHUB_ACTIONS") { |
| 327 | + // SAFETY: bootstrap tests are sequential |
| 328 | + unsafe { std::env::remove_var("GITHUB_ACTIONS") }; |
| 329 | + |
| 330 | + let ret = func(); |
| 331 | + |
| 332 | + // SAFETY: bootstrap tests are sequential |
| 333 | + unsafe { std::env::set_var("GITHUB_ACTIONS", var) }; |
| 334 | + ret |
| 335 | + } else { |
| 336 | + func() |
| 337 | + } |
| 338 | +} |
| 339 | + |
| 340 | +/// Prepares the given directory so that it looks like a rustc checkout. |
| 341 | +/// Also configures `GitCtx` to use the correct merge bot e-mail for upstream merge commits. |
| 342 | +fn prepare_rustc_checkout(ctx: &mut GitCtx) { |
| 343 | + ctx.merge_bot_email = |
| 344 | + format!("Merge bot <{}>", parse_stage0_file().config.git_merge_commit_email); |
| 345 | + ctx.write("src/ci/channel", "nightly"); |
| 346 | + ctx.commit(); |
| 347 | +} |
| 348 | + |
| 349 | +/// Parses a Config directory from `path`, with the given value of `download_rustc`. |
| 350 | +fn parse_config_download_rustc_at(path: &Path, download_rustc: &str) -> Config { |
| 351 | + Config::parse_inner( |
| 352 | + Flags::parse(&[ |
| 353 | + "build".to_owned(), |
| 354 | + "--dry-run".to_owned(), |
| 355 | + format!("--set=rust.download-rustc='{download_rustc}'"), |
| 356 | + "--src".to_owned(), |
| 357 | + path.to_str().unwrap().to_owned(), |
| 358 | + ]), |
| 359 | + |&_| Ok(Default::default()), |
| 360 | + ) |
| 361 | +} |
| 362 | + |
241 | 363 | mod defaults {
|
242 | 364 | use pretty_assertions::assert_eq;
|
243 | 365 |
|
|
0 commit comments