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