]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/profile_config.rs
Move string interning to util
[cargo.git] / tests / testsuite / profile_config.rs
CommitLineData
83571aee
EH
1//! Tests for profiles defined in config files.
2
77ee608d 3use cargo_test_support::paths::CargoPathExt;
51f32532 4use cargo_test_support::registry::Package;
61fb34b0 5use cargo_test_support::{basic_lib_manifest, paths, project};
2f7b5225 6
77ee608d
EH
7#[cargo_test]
8fn named_profile_gated() {
9 // Named profile in config requires enabling in Cargo.toml.
10 let p = project()
11 .file("src/lib.rs", "")
12 .file(
13 ".cargo/config",
14 r#"
15 [profile.foo]
16 inherits = 'dev'
17 opt-level = 1
18 "#,
19 )
20 .build();
8e935d4d 21 p.cargo("build --profile foo -Zunstable-options")
77ee608d
EH
22 .masquerade_as_nightly_cargo()
23 .with_stderr(
24 "\
25[ERROR] config profile `foo` is not valid (defined in `[..]/foo/.cargo/config`)
26
27Caused by:
28 feature `named-profiles` is required
29
6514c289 30 consider adding `cargo-features = [\"named-profiles\"]` to the manifest
77ee608d
EH
31",
32 )
33 .with_status(101)
34 .run();
35}
36
0e0d9688 37#[cargo_test]
2f7b5225 38fn profile_config_validate_warnings() {
7fe2fbc8 39 let p = project()
dda81d31 40 .file("Cargo.toml", &basic_lib_manifest("foo"))
fecb7246 41 .file("src/lib.rs", "")
2f7b5225
EH
42 .file(
43 ".cargo/config",
44 r#"
45 [profile.test]
46 opt-level = 3
47
48 [profile.asdf]
49 opt-level = 3
50
51 [profile.dev]
52 bad-key = true
53
54 [profile.dev.build-override]
55 bad-key-bo = true
56
fcfe0b89 57 [profile.dev.package.bar]
2f7b5225
EH
58 bad-key-bar = true
59 "#,
fecb7246
AC
60 )
61 .build();
2f7b5225 62
8e935d4d 63 p.cargo("build")
85984a87 64 .with_stderr_unordered(
84a80d8f 65 "\
91015d52
EH
66[WARNING] unused config key `profile.dev.bad-key` in `[..].cargo/config`
67[WARNING] unused config key `profile.dev.package.bar.bad-key-bar` in `[..].cargo/config`
68[WARNING] unused config key `profile.dev.build-override.bad-key-bo` in `[..].cargo/config`
84a80d8f
EH
69[COMPILING] foo [..]
70[FINISHED] [..]
2f7b5225 71",
fecb7246
AC
72 )
73 .run();
2f7b5225
EH
74}
75
0e0d9688 76#[cargo_test]
2f7b5225 77fn profile_config_error_paths() {
77ee608d 78 // Errors in config show where the error is located.
7fe2fbc8 79 let p = project()
2f7b5225
EH
80 .file("Cargo.toml", &basic_lib_manifest("foo"))
81 .file("src/lib.rs", "")
82 .file(
83 ".cargo/config",
84 r#"
85 [profile.dev]
86 opt-level = 3
87 "#,
fecb7246
AC
88 )
89 .file(
2f7b5225
EH
90 paths::home().join(".cargo/config"),
91 r#"
92 [profile.dev]
93 rpath = "foo"
94 "#,
fecb7246
AC
95 )
96 .build();
2f7b5225 97
8e935d4d 98 p.cargo("build")
85984a87
DW
99 .with_status(101)
100 .with_stderr(
2f7b5225 101 "\
dafacbb7
EH
102[ERROR] error in [..]/foo/.cargo/config: could not load config key `profile.dev`
103
104Caused by:
105 error in [..]/home/.cargo/config: `profile.dev.rpath` expected true/false, but found a string
2f7b5225 106",
fecb7246
AC
107 )
108 .run();
2f7b5225
EH
109}
110
0e0d9688 111#[cargo_test]
2f7b5225 112fn profile_config_validate_errors() {
7fe2fbc8 113 let p = project()
dda81d31 114 .file("Cargo.toml", &basic_lib_manifest("foo"))
fecb7246 115 .file("src/lib.rs", "")
2f7b5225
EH
116 .file(
117 ".cargo/config",
118 r#"
fcfe0b89 119 [profile.dev.package.foo]
2f7b5225
EH
120 panic = "abort"
121 "#,
fecb7246
AC
122 )
123 .build();
2f7b5225 124
8e935d4d 125 p.cargo("build")
85984a87
DW
126 .with_status(101)
127 .with_stderr(
2f7b5225 128 "\
77ee608d 129[ERROR] config profile `dev` is not valid (defined in `[..]/foo/.cargo/config`)
2f7b5225
EH
130
131Caused by:
fcfe0b89 132 `panic` may not be specified in a `package` profile
2f7b5225 133",
fecb7246
AC
134 )
135 .run();
2f7b5225
EH
136}
137
0e0d9688 138#[cargo_test]
2f7b5225 139fn profile_config_syntax_errors() {
7fe2fbc8 140 let p = project()
2f7b5225
EH
141 .file("Cargo.toml", &basic_lib_manifest("foo"))
142 .file("src/lib.rs", "")
143 .file(
144 ".cargo/config",
145 r#"
146 [profile.dev]
147 codegen-units = "foo"
148 "#,
fecb7246
AC
149 )
150 .build();
2f7b5225 151
8e935d4d 152 p.cargo("build")
85984a87
DW
153 .with_status(101)
154 .with_stderr(
2f7b5225 155 "\
dafacbb7
EH
156[ERROR] error in [..]/.cargo/config: could not load config key `profile.dev`
157
158Caused by:
159 error in [..]/foo/.cargo/config: `profile.dev.codegen-units` expected an integer, but found a string
2f7b5225 160",
fecb7246
AC
161 )
162 .run();
2f7b5225
EH
163}
164
0e0d9688 165#[cargo_test]
2f7b5225 166fn profile_config_override_spec_multiple() {
7fe2fbc8 167 let p = project()
2f7b5225
EH
168 .file(
169 "Cargo.toml",
170 r#"
2f7b5225
EH
171 [package]
172 name = "foo"
173 version = "0.0.1"
174
175 [dependencies]
176 bar = { path = "bar" }
177 "#,
fecb7246
AC
178 )
179 .file(
2f7b5225
EH
180 ".cargo/config",
181 r#"
fcfe0b89 182 [profile.dev.package.bar]
2f7b5225
EH
183 opt-level = 3
184
fcfe0b89 185 [profile.dev.package."bar:0.5.0"]
2f7b5225
EH
186 opt-level = 3
187 "#,
fecb7246
AC
188 )
189 .file("src/lib.rs", "")
dda81d31 190 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
fecb7246 191 .file("bar/src/lib.rs", "")
2f7b5225
EH
192 .build();
193
194 // Unfortunately this doesn't tell you which file, hopefully it's not too
195 // much of a problem.
8e935d4d 196 p.cargo("build -v")
85984a87
DW
197 .with_status(101)
198 .with_stderr(
2f7b5225 199 "\
fcfe0b89
EH
200[ERROR] multiple package overrides in profile `dev` match package `bar v0.5.0 ([..])`
201found package specs: bar, bar:0.5.0",
fecb7246
AC
202 )
203 .run();
2f7b5225
EH
204}
205
0e0d9688 206#[cargo_test]
2f7b5225
EH
207fn profile_config_all_options() {
208 // Ensure all profile options are supported.
7fe2fbc8 209 let p = project()
2b6fd6f0 210 .file("src/main.rs", "fn main() {}")
2f7b5225
EH
211 .file(
212 ".cargo/config",
213 r#"
214 [profile.release]
215 opt-level = 1
216 debug = true
217 debug-assertions = true
218 overflow-checks = false
219 rpath = true
220 lto = true
221 codegen-units = 2
222 panic = "abort"
223 incremental = true
224 "#,
fecb7246
AC
225 )
226 .build();
2f7b5225 227
8e935d4d 228 p.cargo("build --release -v")
2b6fd6f0 229 .env_remove("CARGO_INCREMENTAL")
85984a87 230 .with_stderr(
2f7b5225
EH
231 "\
232[COMPILING] foo [..]
233[RUNNING] `rustc --crate-name foo [..] \
234 -C opt-level=1 \
235 -C panic=abort \
2b6fd6f0 236 -C lto \
2f7b5225
EH
237 -C codegen-units=2 \
238 -C debuginfo=2 \
239 -C debug-assertions=on \
240 -C overflow-checks=off [..]\
2b6fd6f0
EH
241 -C rpath [..]\
242 -C incremental=[..]
2f7b5225
EH
243[FINISHED] release [optimized + debuginfo] [..]
244",
fecb7246
AC
245 )
246 .run();
2f7b5225
EH
247}
248
0e0d9688 249#[cargo_test]
2f7b5225
EH
250fn profile_config_override_precedence() {
251 // Config values take precedence over manifest values.
7fe2fbc8 252 let p = project()
2f7b5225
EH
253 .file(
254 "Cargo.toml",
255 r#"
2f7b5225
EH
256 [package]
257 name = "foo"
258 version = "0.0.1"
259
260 [dependencies]
261 bar = {path = "bar"}
262
263 [profile.dev]
264 codegen-units = 2
265
fcfe0b89 266 [profile.dev.package.bar]
2f7b5225
EH
267 opt-level = 3
268 "#,
fecb7246
AC
269 )
270 .file("src/lib.rs", "")
dda81d31 271 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
fecb7246 272 .file("bar/src/lib.rs", "")
2f7b5225
EH
273 .file(
274 ".cargo/config",
275 r#"
fcfe0b89 276 [profile.dev.package.bar]
2f7b5225
EH
277 opt-level = 2
278 "#,
fecb7246
AC
279 )
280 .build();
2f7b5225 281
8e935d4d 282 p.cargo("build -v")
85984a87 283 .with_stderr(
2f7b5225
EH
284 "\
285[COMPILING] bar [..]
bac300bd 286[RUNNING] `rustc --crate-name bar [..] -C opt-level=2[..]-C codegen-units=2 [..]
2f7b5225
EH
287[COMPILING] foo [..]
288[RUNNING] `rustc --crate-name foo [..]-C codegen-units=2 [..]
289[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
fecb7246
AC
290 )
291 .run();
2f7b5225
EH
292}
293
0e0d9688 294#[cargo_test]
2f7b5225 295fn profile_config_no_warn_unknown_override() {
7fe2fbc8 296 let p = project()
dda81d31 297 .file("Cargo.toml", &basic_lib_manifest("foo"))
fecb7246 298 .file("src/lib.rs", "")
2f7b5225
EH
299 .file(
300 ".cargo/config",
301 r#"
fcfe0b89 302 [profile.dev.package.bar]
2f7b5225
EH
303 codegen-units = 4
304 "#,
fecb7246
AC
305 )
306 .build();
2f7b5225 307
8e935d4d 308 p.cargo("build")
85984a87
DW
309 .with_stderr_does_not_contain("[..]warning[..]")
310 .run();
2f7b5225
EH
311}
312
0e0d9688 313#[cargo_test]
2f7b5225 314fn profile_config_mixed_types() {
7fe2fbc8 315 let p = project()
2f7b5225
EH
316 .file("Cargo.toml", &basic_lib_manifest("foo"))
317 .file("src/lib.rs", "")
318 .file(
319 ".cargo/config",
320 r#"
321 [profile.dev]
322 opt-level = 3
323 "#,
fecb7246
AC
324 )
325 .file(
2f7b5225
EH
326 paths::home().join(".cargo/config"),
327 r#"
328 [profile.dev]
329 opt-level = 's'
330 "#,
fecb7246
AC
331 )
332 .build();
2f7b5225 333
8e935d4d 334 p.cargo("build -v")
85984a87
DW
335 .with_stderr_contains("[..]-C opt-level=3 [..]")
336 .run();
2f7b5225 337}
77ee608d
EH
338
339#[cargo_test]
340fn named_config_profile() {
341 // Exercises config named profies.
342 // foo -> middle -> bar -> dev
343 // middle exists in Cargo.toml, the others in .cargo/config
344 use super::config::ConfigBuilder;
345 use cargo::core::compiler::CompileMode;
346 use cargo::core::enable_nightly_features;
347 use cargo::core::features::Features;
348 use cargo::core::profiles::{Profiles, UnitFor};
7f73a6c7 349 use cargo::core::PackageId;
350 use cargo::util::interning::InternedString;
77ee608d
EH
351 use cargo::util::toml::TomlProfiles;
352 use std::fs;
353 enable_nightly_features();
354 paths::root().join(".cargo").mkdir_p();
355 fs::write(
356 paths::root().join(".cargo/config"),
357 r#"
358 [profile.foo]
359 inherits = "middle"
360 codegen-units = 2
361 [profile.foo.build-override]
362 codegen-units = 6
363 [profile.foo.package.dep]
364 codegen-units = 7
365
366 [profile.middle]
367 inherits = "bar"
368 codegen-units = 3
369
370 [profile.bar]
371 inherits = "dev"
372 codegen-units = 4
373 debug = 1
374 "#,
375 )
376 .unwrap();
8e935d4d 377 let config = ConfigBuilder::new().build();
77ee608d
EH
378 let mut warnings = Vec::new();
379 let features = Features::new(&["named-profiles".to_string()], &mut warnings).unwrap();
380 assert_eq!(warnings.len(), 0);
381 let profile_name = InternedString::new("foo");
382 let toml = r#"
383 [profile.middle]
384 inherits = "bar"
385 codegen-units = 1
386 opt-level = 1
387 [profile.middle.package.dep]
388 overflow-checks = false
389
390 [profile.foo.build-override]
391 codegen-units = 5
392 debug-assertions = false
393 [profile.foo.package.dep]
394 codegen-units = 8
395 "#;
396 #[derive(serde::Deserialize)]
397 struct TomlManifest {
398 profile: Option<TomlProfiles>,
399 }
400 let manifest: TomlManifest = toml::from_str(toml).unwrap();
401 let profiles =
402 Profiles::new(manifest.profile.as_ref(), &config, profile_name, &features).unwrap();
403
404 let crates_io = cargo::core::source::SourceId::crates_io(&config).unwrap();
405 let a_pkg = PackageId::new("a", "0.1.0", crates_io).unwrap();
406 let dep_pkg = PackageId::new("dep", "0.1.0", crates_io).unwrap();
407
408 // normal package
b6a4b074
EH
409 let mode = CompileMode::Build;
410 let p = profiles.get_profile(a_pkg, true, true, UnitFor::new_normal(), mode);
77ee608d
EH
411 assert_eq!(p.name, "foo");
412 assert_eq!(p.codegen_units, Some(2)); // "foo" from config
413 assert_eq!(p.opt_level, "1"); // "middle" from manifest
414 assert_eq!(p.debuginfo, Some(1)); // "bar" from config
415 assert_eq!(p.debug_assertions, true); // "dev" built-in (ignore build-override)
416 assert_eq!(p.overflow_checks, true); // "dev" built-in (ignore package override)
417
418 // build-override
b6a4b074 419 let bo = profiles.get_profile(a_pkg, true, true, UnitFor::new_host(false), mode);
77ee608d
EH
420 assert_eq!(bo.name, "foo");
421 assert_eq!(bo.codegen_units, Some(6)); // "foo" build override from config
422 assert_eq!(bo.opt_level, "1"); // SAME as normal
423 assert_eq!(bo.debuginfo, Some(1)); // SAME as normal
424 assert_eq!(bo.debug_assertions, false); // "foo" build override from manifest
425 assert_eq!(bo.overflow_checks, true); // SAME as normal
426
427 // package overrides
b6a4b074 428 let po = profiles.get_profile(dep_pkg, false, true, UnitFor::new_normal(), mode);
77ee608d
EH
429 assert_eq!(po.name, "foo");
430 assert_eq!(po.codegen_units, Some(7)); // "foo" package override from config
431 assert_eq!(po.opt_level, "1"); // SAME as normal
432 assert_eq!(po.debuginfo, Some(1)); // SAME as normal
433 assert_eq!(po.debug_assertions, true); // SAME as normal
434 assert_eq!(po.overflow_checks, false); // "middle" package override from manifest
435}
436
437#[cargo_test]
438fn named_env_profile() {
439 // Environment variables used to define a named profile.
440 let p = project()
441 .file(
442 "Cargo.toml",
443 r#"
444 cargo-features = ["named-profiles"]
445 [package]
446 name = "foo"
447 version = "0.1.0"
448 "#,
449 )
450 .file("src/lib.rs", "")
451 .build();
452
8e935d4d 453 p.cargo("build -v -Zunstable-options --profile=other")
77ee608d
EH
454 .masquerade_as_nightly_cargo()
455 .env("CARGO_PROFILE_OTHER_CODEGEN_UNITS", "1")
456 .env("CARGO_PROFILE_OTHER_INHERITS", "dev")
457 .with_stderr_contains("[..]-C codegen-units=1 [..]")
458 .run();
459}
51f32532
EH
460
461#[cargo_test]
462fn test_with_dev_profile() {
463 // `cargo test` uses "dev" profile for dependencies.
464 Package::new("somedep", "1.0.0").publish();
465 let p = project()
466 .file(
467 "Cargo.toml",
468 r#"
469 [package]
470 name = "foo"
471 version = "0.1.0"
472
473 [dependencies]
474 somedep = "1.0"
475 "#,
476 )
477 .file("src/lib.rs", "")
478 .build();
479 p.cargo("test --lib --no-run -v")
480 .env("CARGO_PROFILE_DEV_DEBUG", "0")
481 .with_stderr(
482 "\
483[UPDATING] [..]
484[DOWNLOADING] [..]
485[DOWNLOADED] [..]
486[COMPILING] somedep v1.0.0
487[RUNNING] `rustc --crate-name somedep [..]-C debuginfo=0[..]
488[COMPILING] foo v0.1.0 [..]
489[RUNNING] `rustc --crate-name foo [..]-C debuginfo=2[..]
490[FINISHED] [..]
491",
492 )
493 .run();
494}