]>
Commit | Line | Data |
---|---|---|
83571aee EH |
1 | //! Tests for profiles defined in config files. |
2 | ||
77ee608d | 3 | use cargo_test_support::paths::CargoPathExt; |
51f32532 | 4 | use cargo_test_support::registry::Package; |
61fb34b0 | 5 | use cargo_test_support::{basic_lib_manifest, paths, project}; |
2f7b5225 | 6 | |
77ee608d EH |
7 | #[cargo_test] |
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(); | |
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 | ||
27 | Caused 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 | 38 | fn 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 | 77 | fn 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 | ||
104 | Caused 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 | 112 | fn 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 | |
131 | Caused 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 | 139 | fn 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 | ||
158 | Caused 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 | 166 | fn 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 ([..])` |
201 | found package specs: bar, bar:0.5.0", | |
fecb7246 AC |
202 | ) |
203 | .run(); | |
2f7b5225 EH |
204 | } |
205 | ||
0e0d9688 | 206 | #[cargo_test] |
2f7b5225 EH |
207 | fn 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 |
250 | fn 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 | 295 | fn 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 | 314 | fn 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] | |
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::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] | |
438 | fn 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] | |
462 | fn 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 | } |