From 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:41:41 +0200 Subject: Merging upstream version 1.70.0+dfsg2. Signed-off-by: Daniel Baumann --- src/tools/cargo/tests/testsuite/profile_config.rs | 519 ++++++++++++++++++++++ 1 file changed, 519 insertions(+) create mode 100644 src/tools/cargo/tests/testsuite/profile_config.rs (limited to 'src/tools/cargo/tests/testsuite/profile_config.rs') diff --git a/src/tools/cargo/tests/testsuite/profile_config.rs b/src/tools/cargo/tests/testsuite/profile_config.rs new file mode 100644 index 000000000..c59ed7a97 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/profile_config.rs @@ -0,0 +1,519 @@ +//! Tests for profiles defined in config files. + +use cargo_test_support::paths::CargoPathExt; +use cargo_test_support::registry::Package; +use cargo_test_support::{basic_lib_manifest, paths, project}; + +// TODO: this should be remove once -Zprofile-rustflags is stabilized +#[cargo_test] +fn rustflags_works_with_zflag() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + "#, + ) + .file("src/main.rs", "fn main() {}") + .file( + ".cargo/config.toml", + r#" + [profile.dev] + rustflags = ["-C", "link-dead-code=yes"] + "#, + ) + .build(); + + p.cargo("check -v") + .masquerade_as_nightly_cargo(&["profile-rustflags"]) + .with_status(101) + .with_stderr_contains("[..]feature `profile-rustflags` is required[..]") + .run(); + + p.cargo("check -v -Zprofile-rustflags") + .masquerade_as_nightly_cargo(&["profile-rustflags"]) + .with_stderr( + "\ +[CHECKING] foo [..] +[RUNNING] `rustc --crate-name foo [..] -C link-dead-code=yes [..] +[FINISHED] [..] +", + ) + .run(); + + p.change_file( + ".cargo/config.toml", + r#" + [unstable] + profile-rustflags = true + + [profile.dev] + rustflags = ["-C", "link-dead-code=yes"] + "#, + ); + + p.cargo("check -v") + .masquerade_as_nightly_cargo(&["profile-rustflags"]) + .with_stderr( + "\ +[FRESH] foo [..] +[FINISHED] [..] +", + ) + .run(); +} + +#[cargo_test] +fn profile_config_validate_warnings() { + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file("src/lib.rs", "") + .file( + ".cargo/config", + r#" + [profile.test] + opt-level = 3 + + [profile.asdf] + opt-level = 3 + + [profile.dev] + bad-key = true + + [profile.dev.build-override] + bad-key-bo = true + + [profile.dev.package.bar] + bad-key-bar = true + "#, + ) + .build(); + + p.cargo("build") + .with_stderr_unordered( + "\ +[WARNING] unused config key `profile.dev.bad-key` in `[..].cargo/config` +[WARNING] unused config key `profile.dev.package.bar.bad-key-bar` in `[..].cargo/config` +[WARNING] unused config key `profile.dev.build-override.bad-key-bo` in `[..].cargo/config` +[COMPILING] foo [..] +[FINISHED] [..] +", + ) + .run(); +} + +#[cargo_test] +fn profile_config_error_paths() { + // Errors in config show where the error is located. + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file("src/lib.rs", "") + .file( + ".cargo/config", + r#" + [profile.dev] + opt-level = 3 + "#, + ) + .file( + paths::home().join(".cargo/config"), + r#" + [profile.dev] + rpath = "foo" + "#, + ) + .build(); + + p.cargo("build") + .with_status(101) + .with_stderr( + "\ +[ERROR] error in [..]/foo/.cargo/config: could not load config key `profile.dev` + +Caused by: + error in [..]/home/.cargo/config: `profile.dev.rpath` expected true/false, but found a string +", + ) + .run(); +} + +#[cargo_test] +fn profile_config_validate_errors() { + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file("src/lib.rs", "") + .file( + ".cargo/config", + r#" + [profile.dev.package.foo] + panic = "abort" + "#, + ) + .build(); + + p.cargo("build") + .with_status(101) + .with_stderr( + "\ +[ERROR] config profile `dev` is not valid (defined in `[..]/foo/.cargo/config`) + +Caused by: + `panic` may not be specified in a `package` profile +", + ) + .run(); +} + +#[cargo_test] +fn profile_config_syntax_errors() { + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file("src/lib.rs", "") + .file( + ".cargo/config", + r#" + [profile.dev] + codegen-units = "foo" + "#, + ) + .build(); + + p.cargo("build") + .with_status(101) + .with_stderr( + "\ +[ERROR] error in [..]/.cargo/config: could not load config key `profile.dev` + +Caused by: + error in [..]/foo/.cargo/config: `profile.dev.codegen-units` expected an integer, but found a string +", + ) + .run(); +} + +#[cargo_test] +fn profile_config_override_spec_multiple() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + bar = { path = "bar" } + "#, + ) + .file( + ".cargo/config", + r#" + [profile.dev.package.bar] + opt-level = 3 + + [profile.dev.package."bar:0.5.0"] + opt-level = 3 + "#, + ) + .file("src/lib.rs", "") + .file("bar/Cargo.toml", &basic_lib_manifest("bar")) + .file("bar/src/lib.rs", "") + .build(); + + // Unfortunately this doesn't tell you which file, hopefully it's not too + // much of a problem. + p.cargo("build -v") + .with_status(101) + .with_stderr( + "\ +[ERROR] multiple package overrides in profile `dev` match package `bar v0.5.0 ([..])` +found package specs: bar, bar@0.5.0", + ) + .run(); +} + +#[cargo_test] +fn profile_config_all_options() { + // Ensure all profile options are supported. + let p = project() + .file("src/main.rs", "fn main() {}") + .file( + ".cargo/config", + r#" + [profile.release] + opt-level = 1 + debug = true + debug-assertions = true + overflow-checks = false + rpath = true + lto = true + codegen-units = 2 + panic = "abort" + incremental = true + "#, + ) + .build(); + + p.cargo("build --release -v") + .env_remove("CARGO_INCREMENTAL") + .with_stderr( + "\ +[COMPILING] foo [..] +[RUNNING] `rustc --crate-name foo [..] \ + -C opt-level=1 \ + -C panic=abort \ + -C lto[..]\ + -C codegen-units=2 \ + -C debuginfo=2 \ + -C debug-assertions=on \ + -C overflow-checks=off [..]\ + -C rpath [..]\ + -C incremental=[..] +[FINISHED] release [optimized + debuginfo] [..] +", + ) + .run(); +} + +#[cargo_test] +fn profile_config_override_precedence() { + // Config values take precedence over manifest values. + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + bar = {path = "bar"} + + [profile.dev] + codegen-units = 2 + + [profile.dev.package.bar] + opt-level = 3 + "#, + ) + .file("src/lib.rs", "") + .file("bar/Cargo.toml", &basic_lib_manifest("bar")) + .file("bar/src/lib.rs", "") + .file( + ".cargo/config", + r#" + [profile.dev.package.bar] + opt-level = 2 + "#, + ) + .build(); + + p.cargo("build -v") + .with_stderr( + "\ +[COMPILING] bar [..] +[RUNNING] `rustc --crate-name bar [..] -C opt-level=2[..]-C codegen-units=2 [..] +[COMPILING] foo [..] +[RUNNING] `rustc --crate-name foo [..]-C codegen-units=2 [..] +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", + ) + .run(); +} + +#[cargo_test] +fn profile_config_no_warn_unknown_override() { + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file("src/lib.rs", "") + .file( + ".cargo/config", + r#" + [profile.dev.package.bar] + codegen-units = 4 + "#, + ) + .build(); + + p.cargo("build") + .with_stderr_does_not_contain("[..]warning[..]") + .run(); +} + +#[cargo_test] +fn profile_config_mixed_types() { + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file("src/lib.rs", "") + .file( + ".cargo/config", + r#" + [profile.dev] + opt-level = 3 + "#, + ) + .file( + paths::home().join(".cargo/config"), + r#" + [profile.dev] + opt-level = 's' + "#, + ) + .build(); + + p.cargo("build -v") + .with_stderr_contains("[..]-C opt-level=3 [..]") + .run(); +} + +#[cargo_test] +fn named_config_profile() { + // Exercises config named profies. + // foo -> middle -> bar -> dev + // middle exists in Cargo.toml, the others in .cargo/config + use super::config::ConfigBuilder; + use cargo::core::compiler::CompileKind; + use cargo::core::profiles::{Profiles, UnitFor}; + use cargo::core::{PackageId, Workspace}; + use cargo::util::interning::InternedString; + use std::fs; + paths::root().join(".cargo").mkdir_p(); + fs::write( + paths::root().join(".cargo/config"), + r#" + [profile.foo] + inherits = "middle" + codegen-units = 2 + [profile.foo.build-override] + codegen-units = 6 + [profile.foo.package.dep] + codegen-units = 7 + + [profile.middle] + inherits = "bar" + codegen-units = 3 + + [profile.bar] + inherits = "dev" + codegen-units = 4 + debug = 1 + "#, + ) + .unwrap(); + fs::write( + paths::root().join("Cargo.toml"), + r#" + [workspace] + + [profile.middle] + inherits = "bar" + codegen-units = 1 + opt-level = 1 + [profile.middle.package.dep] + overflow-checks = false + + [profile.foo.build-override] + codegen-units = 5 + debug-assertions = false + [profile.foo.package.dep] + codegen-units = 8 + "#, + ) + .unwrap(); + let config = ConfigBuilder::new().build(); + let profile_name = InternedString::new("foo"); + let ws = Workspace::new(&paths::root().join("Cargo.toml"), &config).unwrap(); + let profiles = Profiles::new(&ws, profile_name).unwrap(); + + let crates_io = cargo::core::source::SourceId::crates_io(&config).unwrap(); + let a_pkg = PackageId::new("a", "0.1.0", crates_io).unwrap(); + let dep_pkg = PackageId::new("dep", "0.1.0", crates_io).unwrap(); + + // normal package + let kind = CompileKind::Host; + let p = profiles.get_profile(a_pkg, true, true, UnitFor::new_normal(kind), kind); + assert_eq!(p.name, "foo"); + assert_eq!(p.codegen_units, Some(2)); // "foo" from config + assert_eq!(p.opt_level, "1"); // "middle" from manifest + assert_eq!(p.debuginfo.to_option(), Some(1)); // "bar" from config + assert_eq!(p.debug_assertions, true); // "dev" built-in (ignore build-override) + assert_eq!(p.overflow_checks, true); // "dev" built-in (ignore package override) + + // build-override + let bo = profiles.get_profile(a_pkg, true, true, UnitFor::new_host(false, kind), kind); + assert_eq!(bo.name, "foo"); + assert_eq!(bo.codegen_units, Some(6)); // "foo" build override from config + assert_eq!(bo.opt_level, "0"); // default to zero + assert_eq!(bo.debuginfo.to_option(), Some(1)); // SAME as normal + assert_eq!(bo.debug_assertions, false); // "foo" build override from manifest + assert_eq!(bo.overflow_checks, true); // SAME as normal + + // package overrides + let po = profiles.get_profile(dep_pkg, false, true, UnitFor::new_normal(kind), kind); + assert_eq!(po.name, "foo"); + assert_eq!(po.codegen_units, Some(7)); // "foo" package override from config + assert_eq!(po.opt_level, "1"); // SAME as normal + assert_eq!(po.debuginfo.to_option(), Some(1)); // SAME as normal + assert_eq!(po.debug_assertions, true); // SAME as normal + assert_eq!(po.overflow_checks, false); // "middle" package override from manifest +} + +#[cargo_test] +fn named_env_profile() { + // Environment variables used to define a named profile. + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("build -v --profile=other") + .env("CARGO_PROFILE_OTHER_CODEGEN_UNITS", "1") + .env("CARGO_PROFILE_OTHER_INHERITS", "dev") + .with_stderr_contains("[..]-C codegen-units=1 [..]") + .run(); +} + +#[cargo_test] +fn test_with_dev_profile() { + // The `test` profile inherits from `dev` for both local crates and + // dependencies. + Package::new("somedep", "1.0.0").publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + somedep = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("test --lib --no-run -v") + .env("CARGO_PROFILE_DEV_DEBUG", "0") + .with_stderr( + "\ +[UPDATING] [..] +[DOWNLOADING] [..] +[DOWNLOADED] [..] +[COMPILING] somedep v1.0.0 +[RUNNING] `rustc --crate-name somedep [..]-C debuginfo=0[..] +[COMPILING] foo v0.1.0 [..] +[RUNNING] `rustc --crate-name foo [..]-C debuginfo=0[..] +[FINISHED] [..] +[EXECUTABLE] `[..]/target/debug/deps/foo-[..][EXE]` +", + ) + .run(); +} -- cgit v1.2.3