From 208f817c83f6bc93d888953564e2807074598554 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 2 Jan 2025 17:13:00 +0100 Subject: [PATCH 1/3] Add preparatory tests for `lib.test = false` check-cfg changes --- tests/testsuite/check_cfg.rs | 121 +++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/tests/testsuite/check_cfg.rs b/tests/testsuite/check_cfg.rs index 2e03254337a..0b3a8d45a91 100644 --- a/tests/testsuite/check_cfg.rs +++ b/tests/testsuite/check_cfg.rs @@ -317,6 +317,127 @@ fn well_known_names_values_doctest() { .run(); } +#[cargo_test] +fn test_false_lib() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [lib] + test = false + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); + + p.cargo("clean").run(); + p.cargo("test -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); + + p.cargo("clean").run(); + p.cargo("test --lib -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); +} + +#[cargo_test] +fn test_false_bins() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [[bin]] + name = "daemon" + test = false + path = "src/deamon.rs" + "#, + ) + .file("src/main.rs", "fn main() {}") + .file("src/deamon.rs", "fn main() {}") + .build(); + + p.cargo("check -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) // for foo & deamon + .run(); +} + +#[cargo_test] +fn test_false_examples() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [lib] + test = false + + [[example]] + name = "daemon" + test = false + path = "src/deamon.rs" + "#, + ) + .file("src/lib.rs", "") + .file("src/deamon.rs", "fn main() {}") + .build(); + + p.cargo("check --examples -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); +} + +#[cargo_test(nightly, reason = "bench is nightly")] +fn test_false_benches() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.0" + edition = "2018" + + [[bench]] + name = "ben1" + test = false + path = "benches/ben1.rs" + "#, + ) + .file("src/lib.rs", "") + .file( + "benches/ben1.rs", + r#" + #![feature(test)] + extern crate test; + #[bench] fn run1(_ben: &mut test::Bencher) { } + "#, + ) + .build(); + + p.cargo("bench --bench ben1 -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); +} + #[cargo_test] fn features_doc() { let p = project() From 2593b86ee1292f4a31dfeda5c28b06f9d004b8fd Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 2 Jan 2025 18:18:05 +0100 Subject: [PATCH 2/3] Conditionally mark the `test` cfg as a well known cfg --- src/cargo/core/compiler/mod.rs | 19 ++++++++++++++----- src/doc/src/reference/cargo-targets.md | 5 ++++- tests/testsuite/check_cfg.rs | 13 ++++++++----- tests/testsuite/test.rs | 19 +++++++++++++++++-- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 277039685d6..9d0181bf8c4 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -1391,17 +1391,26 @@ fn check_cfg_args(unit: &Unit) -> Vec { } arg_feature.push("))"); - // In addition to the package features, we also include the `test` cfg (since - // compiler-team#785, as to be able to someday apply yt conditionaly), as well - // the `docsrs` cfg from the docs.rs service. + // In addition to the package features, we also conditionaly include the `test` cfg + // based on the unit target "test" field (ie `lib.test = false`, `[[bin]] test = false` and + // others). // - // We include `docsrs` here (in Cargo) instead of rustc, since there is a much closer + // We also include `docsrs` here (in Cargo) instead of rustc, since there is a much closer // relationship between Cargo and docs.rs than rustc and docs.rs. In particular, all // users of docs.rs use Cargo, but not all users of rustc (like Rust-for-Linux) use docs.rs. + let arg_extra = if unit.target.tested() + // Benchmarks default to `test = false` but most of them still use the test crate + // and the `#[test]` attribute, so for now always mark `test` as well known for them. + || unit.target.is_bench() + { + OsString::from("cfg(docsrs,test)") + } else { + OsString::from("cfg(docsrs)") + }; vec![ OsString::from("--check-cfg"), - OsString::from("cfg(docsrs,test)"), + arg_extra, OsString::from("--check-cfg"), arg_feature, ] diff --git a/src/doc/src/reference/cargo-targets.md b/src/doc/src/reference/cargo-targets.md index 8a4ed59e54b..aef7abff26b 100644 --- a/src/doc/src/reference/cargo-targets.md +++ b/src/doc/src/reference/cargo-targets.md @@ -216,7 +216,10 @@ the target name. ### The `test` field The `test` field indicates whether or not the target is tested by default by -[`cargo test`]. The default is `true` for lib, bins, and tests. +[`cargo test`], and whenever the target is expected to have tests. Warnings +may be reported when tests are unexpected (i.e., `test = false`). + +The default is `true` for lib, bins, and tests. > **Note**: Examples are built by [`cargo test`] by default to ensure they > continue to compile, but they are not *tested* by default. Setting `test = diff --git a/tests/testsuite/check_cfg.rs b/tests/testsuite/check_cfg.rs index 0b3a8d45a91..3f236118d07 100644 --- a/tests/testsuite/check_cfg.rs +++ b/tests/testsuite/check_cfg.rs @@ -336,17 +336,18 @@ fn test_false_lib() { .build(); p.cargo("check -v") - .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .with_stderr_does_not_contain(x!("rustc" => "cfg" of "docsrs,test")) + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) .run(); p.cargo("clean").run(); p.cargo("test -v") - .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) .run(); p.cargo("clean").run(); p.cargo("test --lib -v") - .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) .run(); } @@ -372,7 +373,8 @@ fn test_false_bins() { .build(); p.cargo("check -v") - .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) // for foo & deamon + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) // for foo + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) // for deamon .run(); } @@ -401,7 +403,8 @@ fn test_false_examples() { .build(); p.cargo("check --examples -v") - .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .with_stderr_does_not_contain(x!("rustc" => "cfg" of "docsrs,test")) + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) .run(); } diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index 48d69526ad7..98212097a2a 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -4191,7 +4191,19 @@ fn test_hint_workspace_virtual() { .file("a/src/lib.rs", "#[test] fn t1() {}") .file("b/Cargo.toml", &basic_manifest("b", "0.1.0")) .file("b/src/lib.rs", "#[test] fn t1() {assert!(false)}") - .file("c/Cargo.toml", &basic_manifest("c", "0.1.0")) + .file( + "c/Cargo.toml", + r#" + [package] + name = "c" + version = "0.1.0" + edition = "2015" + + [[example]] + name = "ex1" + test = true + "#, + ) .file( "c/src/lib.rs", r#" @@ -4275,14 +4287,17 @@ fn test_hint_workspace_virtual() { [ERROR] test failed, to rerun pass `-p c --bin c` [RUNNING] tests/t1.rs (target/debug/deps/t1-[HASH][EXE]) [ERROR] test failed, to rerun pass `-p c --test t1` +[RUNNING] unittests examples/ex1.rs (target/debug/examples/ex1-[HASH][EXE]) +[ERROR] test failed, to rerun pass `-p c --example ex1` [DOCTEST] a [DOCTEST] b [DOCTEST] c [ERROR] doctest failed, to rerun pass `-p c --doc` -[ERROR] 4 targets failed: +[ERROR] 5 targets failed: `-p b --lib` `-p c --bin c` `-p c --test t1` + `-p c --example ex1` `-p c --doc` "#]]) From b757af988bba1eaefa418dbb37fbf303a297ae6b Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 4 Jan 2025 12:06:39 +0100 Subject: [PATCH 3/3] Add stderr checking for the conditional `test` well known cfg --- tests/testsuite/check_cfg.rs | 85 +++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/tests/testsuite/check_cfg.rs b/tests/testsuite/check_cfg.rs index 3f236118d07..0f76cc3ca7d 100644 --- a/tests/testsuite/check_cfg.rs +++ b/tests/testsuite/check_cfg.rs @@ -317,7 +317,7 @@ fn well_known_names_values_doctest() { .run(); } -#[cargo_test] +#[cargo_test(nightly, reason = "warning currently only on nightly")] fn test_false_lib() { let p = project() .file( @@ -332,26 +332,57 @@ fn test_false_lib() { test = false "#, ) - .file("src/lib.rs", "") + .file("src/lib.rs", "#[cfg(test)] mod tests {}") .build(); p.cargo("check -v") .with_stderr_does_not_contain(x!("rustc" => "cfg" of "docsrs,test")) .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (lib) generated 1 warning +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); p.cargo("clean").run(); p.cargo("test -v") .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (lib) generated 1 warning +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[DOCTEST] foo +[RUNNING] [..] + +"#]]) .run(); p.cargo("clean").run(); p.cargo("test --lib -v") .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` + --> src/lib.rs:1:7 +... + +[WARNING] `foo` (lib test) generated 1 warning +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `[ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` + +"#]]) .run(); } -#[cargo_test] +#[cargo_test(nightly, reason = "warning currently only on nightly")] fn test_false_bins() { let p = project() .file( @@ -368,17 +399,26 @@ fn test_false_bins() { path = "src/deamon.rs" "#, ) - .file("src/main.rs", "fn main() {}") - .file("src/deamon.rs", "fn main() {}") + .file("src/main.rs", "fn main() {}\n#[cfg(test)] mod tests {}") + .file("src/deamon.rs", "fn main() {}\n#[cfg(test)] mod tests {}") .build(); p.cargo("check -v") .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) // for foo .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) // for deamon + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (bin "daemon") generated 1 warning +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } -#[cargo_test] +#[cargo_test(nightly, reason = "warning currently only on nightly")] fn test_false_examples() { let p = project() .file( @@ -398,17 +438,34 @@ fn test_false_examples() { path = "src/deamon.rs" "#, ) - .file("src/lib.rs", "") - .file("src/deamon.rs", "fn main() {}") + .file("src/lib.rs", "#[cfg(test)] mod tests {}") + .file("src/deamon.rs", "fn main() {}\n#[cfg(test)] mod tests {}") .build(); p.cargo("check --examples -v") .with_stderr_does_not_contain(x!("rustc" => "cfg" of "docsrs,test")) .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (lib) generated 1 warning +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (example "daemon") generated 1 warning +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } -#[cargo_test(nightly, reason = "bench is nightly")] +#[cargo_test( + nightly, + reason = "bench is nightly & warning currently only on nightly" +)] fn test_false_benches() { let p = project() .file( @@ -436,8 +493,14 @@ fn test_false_benches() { ) .build(); - p.cargo("bench --bench ben1 -v") - .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + // Benches always require the `test` cfg, there should be no warning. + p.cargo("bench --bench ben1") + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `bench` profile [optimized] target(s) in [ELAPSED]s +[RUNNING] benches/ben1.rs (target/release/deps/ben1-[HASH][EXE]) + +"#]]) .run(); }