From ca5961462055f52882a3ef44fd531158c06779df Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sun, 15 Dec 2024 19:01:30 -0500 Subject: [PATCH] test(build-std): Isolate output test to avoid spurious [BLOCKING] messages from concurrent runs 47c2095b1dd580a91e42cb6197b58a318526b8c4 didn't really fix the flakiness. build-std tests use the users `CARGO_HOME` for downloading registry dependencies of the standard library. This reduces disk needs of the tests, speeds up the tests, and reduces the number of network requests that could fail. However, this means all of the tests access the same locks for the package cache. In one test, we assert on the output and a `[BLOCKING]` message can show up, depending on test execution time from concurrent test runs. We are going to hack around this by having the one test that asserts on test output to use the standard `cargo-test-support` `CARGO_HOME`, rather than the users `CARGO_HOME`. There will then only be one process accessing the lock and no `[BLOCKING]` messages. --- tests/build-std/main.rs | 49 +++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/tests/build-std/main.rs b/tests/build-std/main.rs index f8d5e748ac5..32771a01a19 100644 --- a/tests/build-std/main.rs +++ b/tests/build-std/main.rs @@ -25,9 +25,11 @@ use cargo_test_support::{basic_manifest, paths, project, rustc_host, str, Execs} use std::env; use std::path::Path; -fn enable_build_std(e: &mut Execs, arg: Option<&str>) { - e.env_remove("CARGO_HOME"); - e.env_remove("HOME"); +fn enable_build_std(e: &mut Execs, arg: Option<&str>, isolated: bool) { + if !isolated { + e.env_remove("CARGO_HOME"); + e.env_remove("HOME"); + } // And finally actually enable `build-std` for now let arg = match arg { @@ -40,19 +42,41 @@ fn enable_build_std(e: &mut Execs, arg: Option<&str>) { // Helper methods used in the tests below trait BuildStd: Sized { + /// Set `-Zbuild-std` args and will download dependencies of the standard + /// library in users's `CARGO_HOME` (`~/.cargo/`) instead of isolated + /// environment `cargo-test-support` usually provides. + /// + /// The environment is not isolated is to avoid excessive network requests + /// and downloads. A side effect is `[BLOCKING]` will show up in stderr, + /// as a sign of package cahce lock contention when running other build-std + /// tests concurrently. fn build_std(&mut self) -> &mut Self; + + /// Like [`BuildStd::build_std`] and is able to specify what crates to build. fn build_std_arg(&mut self, arg: &str) -> &mut Self; + + /// Like [`BuildStd::build_std`] but use an isolated `CARGO_HOME` environment + /// to avoid package cache lock contention. + /// + /// Don't use this unless you really need to assert the full stderr + /// and avoid any `[BLOCKING]` message. + fn build_std_isolated(&mut self) -> &mut Self; fn target_host(&mut self) -> &mut Self; } impl BuildStd for Execs { fn build_std(&mut self) -> &mut Self { - enable_build_std(self, None); + enable_build_std(self, None, false); self } fn build_std_arg(&mut self, arg: &str) -> &mut Self { - enable_build_std(self, Some(arg)); + enable_build_std(self, Some(arg), false); + self + } + + fn build_std_isolated(&mut self) -> &mut Self { + enable_build_std(self, None, true); self } @@ -107,9 +131,12 @@ fn basic() { ) .build(); - p.cargo("check").build_std().target_host().run(); + // HACK: use an isolated the isolated CARGO_HOME environment (`build_std_isolated`) + // to avoid `[BLOCKING]` messages (from lock contention with other tests) + // from getting in this test's asserts + p.cargo("check").build_std_isolated().target_host().run(); p.cargo("build") - .build_std() + .build_std_isolated() .target_host() // Importantly, this should not say [UPDATING] // There have been multiple bugs where every build triggers and update. @@ -120,7 +147,7 @@ fn basic() { "#]]) .run(); p.cargo("run") - .build_std() + .build_std_isolated() .target_host() .with_stderr_data(str![[r#" [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -129,7 +156,7 @@ fn basic() { "#]]) .run(); p.cargo("test") - .build_std() + .build_std_isolated() .target_host() .with_stderr_data(str![[r#" [COMPILING] rustc-std-workspace-std [..] @@ -379,13 +406,11 @@ fn test_proc_macro() { .file("src/lib.rs", "") .build(); - // Download dependencies first, - // so we can compare `cargo test` output without any wildcard - p.cargo("fetch").build_std().run(); p.cargo("test --lib") .env_remove(cargo_util::paths::dylib_path_envvar()) .build_std() .with_stderr_data(str![[r#" +... [COMPILING] foo v0.0.0 ([ROOT]/foo) [FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] unittests src/lib.rs (target/debug/deps/foo-[HASH])