]>
Commit | Line | Data |
---|---|---|
be28b58b EH |
1 | //! Tests for checking behavior of old cargos. |
2 | //! | |
3 | //! These tests are ignored because it is intended to be run on a developer | |
4 | //! system with a bunch of toolchains installed. This requires `rustup` to be | |
5 | //! installed. It will iterate over installed toolchains, and run some tests | |
6 | //! over each one, producing a report at the end. As of this writing, I have | |
7 | //! tested 1.0 to 1.51. Run this with: | |
8 | //! | |
9 | //! ```console | |
10 | //! cargo test --test testsuite -- old_cargos --nocapture --ignored | |
11 | //! ``` | |
12 | ||
be28b58b EH |
13 | use cargo::CargoResult; |
14 | use cargo_test_support::paths::CargoPathExt; | |
15 | use cargo_test_support::registry::{self, Dependency, Package}; | |
0d4137f4 | 16 | use cargo_test_support::{cargo_exe, execs, paths, process, project, rustc_host}; |
88810035 | 17 | use cargo_util::{ProcessBuilder, ProcessError}; |
be28b58b EH |
18 | use semver::Version; |
19 | use std::fs; | |
20 | ||
21 | fn tc_process(cmd: &str, toolchain: &str) -> ProcessBuilder { | |
c73765f9 | 22 | let mut p = if toolchain == "this" { |
be28b58b EH |
23 | if cmd == "cargo" { |
24 | process(&cargo_exe()) | |
25 | } else { | |
26 | process(cmd) | |
27 | } | |
28 | } else { | |
29 | let mut cmd = process(cmd); | |
30 | cmd.arg(format!("+{}", toolchain)); | |
31 | cmd | |
c73765f9 EH |
32 | }; |
33 | // Reset PATH since `process` modifies it to remove rustup. | |
34 | p.env("PATH", std::env::var_os("PATH").unwrap()); | |
35 | p | |
be28b58b EH |
36 | } |
37 | ||
38 | /// Returns a sorted list of all toolchains. | |
39 | /// | |
40 | /// The returned value includes the parsed version, and the rustup toolchain | |
41 | /// name as a string. | |
42 | fn collect_all_toolchains() -> Vec<(Version, String)> { | |
43 | let rustc_version = |tc| { | |
44 | let mut cmd = tc_process("rustc", tc); | |
45 | cmd.arg("-V"); | |
46 | let output = cmd.exec_with_output().expect("rustc installed"); | |
47 | let version = std::str::from_utf8(&output.stdout).unwrap(); | |
48 | let parts: Vec<_> = version.split_whitespace().collect(); | |
49 | assert_eq!(parts[0], "rustc"); | |
50 | assert!(parts[1].starts_with("1.")); | |
51 | Version::parse(parts[1]).expect("valid version") | |
52 | }; | |
53 | ||
54 | // Provide a way to override the list. | |
55 | if let Ok(tcs) = std::env::var("OLD_CARGO") { | |
56 | return tcs | |
57 | .split(',') | |
58 | .map(|tc| (rustc_version(tc), tc.to_string())) | |
59 | .collect(); | |
60 | } | |
61 | ||
62 | let host = rustc_host(); | |
63 | // I tend to have lots of toolchains installed, but I don't want to test | |
64 | // all of them (like dated nightlies, or toolchains for non-host targets). | |
65 | let valid_names = &[ | |
66 | format!("stable-{}", host), | |
67 | format!("beta-{}", host), | |
68 | format!("nightly-{}", host), | |
69 | ]; | |
70 | ||
88810035 | 71 | let output = ProcessBuilder::new("rustup") |
be28b58b EH |
72 | .args(&["toolchain", "list"]) |
73 | .exec_with_output() | |
74 | .expect("rustup should be installed"); | |
75 | let stdout = std::str::from_utf8(&output.stdout).unwrap(); | |
76 | let mut toolchains: Vec<_> = stdout | |
77 | .lines() | |
78 | .map(|line| { | |
79 | // Some lines say things like (default), just get the version. | |
80 | line.split_whitespace().next().expect("non-empty line") | |
81 | }) | |
82 | .filter(|line| { | |
83 | line.ends_with(&host) | |
84 | && (line.starts_with("1.") || valid_names.iter().any(|name| name == line)) | |
85 | }) | |
86 | .map(|line| (rustc_version(line), line.to_string())) | |
87 | .collect(); | |
88 | ||
89 | // Also include *this* cargo. | |
90 | toolchains.push((rustc_version("this"), "this".to_string())); | |
91 | toolchains.sort_by(|a, b| a.0.cmp(&b.0)); | |
92 | toolchains | |
93 | } | |
94 | ||
95 | // This is a test for exercising the behavior of older versions of cargo with | |
96 | // the new feature syntax. | |
97 | // | |
98 | // The test involves a few dependencies with different feature requirements: | |
99 | // | |
100 | // * `bar` 1.0.0 is the base version that does not use the new syntax. | |
101 | // * `bar` 1.0.1 has a feature with the new syntax, but the feature is unused. | |
102 | // The optional dependency `new-baz-dep` should not be activated. | |
103 | // * `bar` 1.0.2 has a dependency on `baz` that *requires* the new feature | |
104 | // syntax. | |
105 | #[ignore] | |
106 | #[cargo_test] | |
107 | fn new_features() { | |
108 | if std::process::Command::new("rustup").output().is_err() { | |
109 | panic!("old_cargos requires rustup to be installed"); | |
110 | } | |
111 | Package::new("new-baz-dep", "1.0.0").publish(); | |
112 | ||
113 | Package::new("baz", "1.0.0").publish(); | |
114 | let baz101_cksum = Package::new("baz", "1.0.1") | |
115 | .add_dep(Dependency::new("new-baz-dep", "1.0").optional(true)) | |
116 | .feature("new-feat", &["dep:new-baz-dep"]) | |
117 | .publish(); | |
118 | ||
119 | let bar100_cksum = Package::new("bar", "1.0.0") | |
120 | .add_dep(Dependency::new("baz", "1.0").optional(true)) | |
121 | .feature("feat", &["baz"]) | |
122 | .publish(); | |
123 | let bar101_cksum = Package::new("bar", "1.0.1") | |
124 | .add_dep(Dependency::new("baz", "1.0").optional(true)) | |
125 | .feature("feat", &["dep:baz"]) | |
126 | .publish(); | |
127 | let bar102_cksum = Package::new("bar", "1.0.2") | |
128 | .add_dep(Dependency::new("baz", "1.0").enable_features(&["new-feat"])) | |
129 | .publish(); | |
130 | ||
131 | let p = project() | |
132 | .file( | |
133 | "Cargo.toml", | |
134 | r#" | |
135 | [package] | |
136 | name = "foo" | |
137 | version = "0.1.0" | |
138 | ||
139 | [dependencies] | |
140 | bar = "1.0" | |
141 | "#, | |
142 | ) | |
143 | .file("src/lib.rs", "") | |
144 | .build(); | |
145 | ||
146 | let lock_bar_to = |toolchain_version: &Version, bar_version| { | |
147 | let lock = if toolchain_version < &Version::new(1, 12, 0) { | |
148 | let url = registry::registry_url(); | |
149 | match bar_version { | |
150 | 100 => format!( | |
151 | r#" | |
152 | [root] | |
153 | name = "foo" | |
154 | version = "0.1.0" | |
155 | dependencies = [ | |
156 | "bar 1.0.0 (registry+{url})", | |
157 | ] | |
158 | ||
159 | [[package]] | |
160 | name = "bar" | |
161 | version = "1.0.0" | |
162 | source = "registry+{url}" | |
163 | "#, | |
164 | url = url | |
165 | ), | |
166 | 101 => format!( | |
167 | r#" | |
168 | [root] | |
169 | name = "foo" | |
170 | version = "0.1.0" | |
171 | dependencies = [ | |
172 | "bar 1.0.1 (registry+{url})", | |
173 | ] | |
174 | ||
175 | [[package]] | |
176 | name = "bar" | |
177 | version = "1.0.1" | |
178 | source = "registry+{url}" | |
179 | "#, | |
180 | url = url | |
181 | ), | |
182 | 102 => format!( | |
183 | r#" | |
184 | [root] | |
185 | name = "foo" | |
186 | version = "0.1.0" | |
187 | dependencies = [ | |
188 | "bar 1.0.2 (registry+{url})", | |
189 | ] | |
190 | ||
191 | [[package]] | |
192 | name = "bar" | |
193 | version = "1.0.2" | |
194 | source = "registry+{url}" | |
195 | dependencies = [ | |
196 | "baz 1.0.1 (registry+{url})", | |
197 | ] | |
198 | ||
199 | [[package]] | |
200 | name = "baz" | |
201 | version = "1.0.1" | |
202 | source = "registry+{url}" | |
203 | "#, | |
204 | url = url | |
205 | ), | |
206 | _ => panic!("unexpected version"), | |
207 | } | |
208 | } else { | |
209 | match bar_version { | |
210 | 100 => format!( | |
211 | r#" | |
212 | [root] | |
213 | name = "foo" | |
214 | version = "0.1.0" | |
215 | dependencies = [ | |
216 | "bar 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
217 | ] | |
218 | ||
219 | [[package]] | |
220 | name = "bar" | |
221 | version = "1.0.0" | |
222 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
223 | ||
224 | [metadata] | |
225 | "checksum bar 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "{}" | |
226 | "#, | |
227 | bar100_cksum | |
228 | ), | |
229 | 101 => format!( | |
230 | r#" | |
231 | [root] | |
232 | name = "foo" | |
233 | version = "0.1.0" | |
234 | dependencies = [ | |
235 | "bar 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
236 | ] | |
237 | ||
238 | [[package]] | |
239 | name = "bar" | |
240 | version = "1.0.1" | |
241 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
242 | ||
243 | [metadata] | |
244 | "checksum bar 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "{}" | |
245 | "#, | |
246 | bar101_cksum | |
247 | ), | |
248 | 102 => format!( | |
249 | r#" | |
250 | [root] | |
251 | name = "foo" | |
252 | version = "0.1.0" | |
253 | dependencies = [ | |
254 | "bar 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
255 | ] | |
256 | ||
257 | [[package]] | |
258 | name = "bar" | |
259 | version = "1.0.2" | |
260 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
261 | dependencies = [ | |
262 | "baz 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
263 | ] | |
264 | ||
265 | [[package]] | |
266 | name = "baz" | |
267 | version = "1.0.1" | |
268 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
269 | ||
270 | [metadata] | |
271 | "checksum bar 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "{bar102_cksum}" | |
272 | "checksum baz 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "{baz101_cksum}" | |
273 | "#, | |
274 | bar102_cksum = bar102_cksum, | |
275 | baz101_cksum = baz101_cksum | |
276 | ), | |
277 | _ => panic!("unexpected version"), | |
278 | } | |
279 | }; | |
280 | p.change_file("Cargo.lock", &lock); | |
281 | }; | |
282 | ||
283 | let toolchains = collect_all_toolchains(); | |
284 | ||
285 | let config_path = paths::home().join(".cargo/config"); | |
286 | let lock_path = p.root().join("Cargo.lock"); | |
287 | ||
288 | struct ToolchainBehavior { | |
289 | bar: Option<Version>, | |
290 | baz: Option<Version>, | |
291 | new_baz_dep: Option<Version>, | |
292 | } | |
293 | ||
294 | // Collect errors to print at the end. One entry per toolchain, a list of | |
295 | // strings to print. | |
296 | let mut unexpected_results: Vec<Vec<String>> = Vec::new(); | |
297 | ||
298 | for (version, toolchain) in &toolchains { | |
299 | let mut tc_result = Vec::new(); | |
300 | // Write a config appropriate for this version. | |
301 | if version < &Version::new(1, 12, 0) { | |
302 | fs::write( | |
303 | &config_path, | |
304 | format!( | |
305 | r#" | |
306 | [registry] | |
307 | index = "{}" | |
308 | "#, | |
309 | registry::registry_url() | |
310 | ), | |
311 | ) | |
312 | .unwrap(); | |
313 | } else { | |
314 | fs::write( | |
315 | &config_path, | |
316 | format!( | |
317 | " | |
318 | [source.crates-io] | |
319 | registry = 'https://wut' # only needed by 1.12 | |
320 | replace-with = 'dummy-registry' | |
321 | ||
322 | [source.dummy-registry] | |
323 | registry = '{}' | |
324 | ", | |
325 | registry::registry_url() | |
326 | ), | |
327 | ) | |
328 | .unwrap(); | |
329 | } | |
330 | ||
331 | // Fetches the version of a package in the lock file. | |
332 | let pkg_version = |pkg| -> Option<Version> { | |
333 | let output = tc_process("cargo", toolchain) | |
334 | .args(&["pkgid", pkg]) | |
335 | .cwd(p.root()) | |
336 | .exec_with_output() | |
337 | .ok()?; | |
338 | let stdout = std::str::from_utf8(&output.stdout).unwrap(); | |
339 | let version = stdout | |
340 | .trim() | |
341 | .rsplitn(2, ':') | |
342 | .next() | |
343 | .expect("version after colon"); | |
344 | Some(Version::parse(version).expect("parseable version")) | |
345 | }; | |
346 | ||
347 | // Runs `cargo build` and returns the versions selected in the lock. | |
348 | let run_cargo = || -> CargoResult<ToolchainBehavior> { | |
349 | match tc_process("cargo", toolchain) | |
350 | .args(&["build", "--verbose"]) | |
351 | .cwd(p.root()) | |
352 | .exec_with_output() | |
353 | { | |
354 | Ok(_output) => { | |
355 | eprintln!("{} ok", toolchain); | |
356 | let bar = pkg_version("bar"); | |
357 | let baz = pkg_version("baz"); | |
358 | let new_baz_dep = pkg_version("new-baz-dep"); | |
359 | Ok(ToolchainBehavior { | |
360 | bar, | |
361 | baz, | |
362 | new_baz_dep, | |
363 | }) | |
364 | } | |
365 | Err(e) => { | |
366 | eprintln!("{} err {}", toolchain, e); | |
367 | Err(e) | |
368 | } | |
369 | } | |
370 | }; | |
371 | ||
372 | macro_rules! check_lock { | |
373 | ($tc_result:ident, $pkg:expr, $which:expr, $actual:expr, None) => { | |
374 | check_lock!(= $tc_result, $pkg, $which, $actual, None); | |
375 | }; | |
376 | ($tc_result:ident, $pkg:expr, $which:expr, $actual:expr, $expected:expr) => { | |
377 | check_lock!(= $tc_result, $pkg, $which, $actual, Some(Version::parse($expected).unwrap())); | |
378 | }; | |
379 | (= $tc_result:ident, $pkg:expr, $which:expr, $actual:expr, $expected:expr) => { | |
380 | let exp: Option<Version> = $expected; | |
381 | if $actual != $expected { | |
382 | $tc_result.push(format!( | |
383 | "{} for {} saw {:?} but expected {:?}", | |
384 | $which, $pkg, $actual, exp | |
385 | )); | |
386 | } | |
387 | }; | |
388 | } | |
389 | ||
390 | let check_err_contains = |tc_result: &mut Vec<_>, err: anyhow::Error, contents| { | |
391 | if let Some(ProcessError { | |
392 | stderr: Some(stderr), | |
393 | .. | |
394 | }) = err.downcast_ref::<ProcessError>() | |
395 | { | |
e58c544f | 396 | let stderr = std::str::from_utf8(stderr).unwrap(); |
be28b58b EH |
397 | if !stderr.contains(contents) { |
398 | tc_result.push(format!( | |
399 | "{} expected to see error contents:\n{}\nbut saw:\n{}", | |
400 | toolchain, contents, stderr | |
401 | )); | |
402 | } | |
403 | } else { | |
404 | panic!("{} unexpected error {}", toolchain, err); | |
405 | } | |
406 | }; | |
407 | ||
408 | // Unlocked behavior. | |
409 | let which = "unlocked"; | |
410 | lock_path.rm_rf(); | |
411 | p.build_dir().rm_rf(); | |
412 | match run_cargo() { | |
413 | Ok(behavior) => { | |
414 | // TODO: Switch to 51 after backport. | |
415 | if version < &Version::new(1, 52, 0) && toolchain != "this" { | |
416 | check_lock!(tc_result, "bar", which, behavior.bar, "1.0.2"); | |
417 | check_lock!(tc_result, "baz", which, behavior.baz, "1.0.1"); | |
418 | check_lock!(tc_result, "new-baz-dep", which, behavior.new_baz_dep, None); | |
419 | } else { | |
420 | check_lock!(tc_result, "bar", which, behavior.bar, "1.0.0"); | |
421 | check_lock!(tc_result, "baz", which, behavior.baz, None); | |
422 | check_lock!(tc_result, "new-baz-dep", which, behavior.new_baz_dep, None); | |
423 | } | |
424 | } | |
425 | Err(e) => { | |
426 | tc_result.push(format!("unlocked build failed: {}", e)); | |
427 | } | |
428 | } | |
429 | ||
430 | let which = "locked bar 1.0.0"; | |
e58c544f | 431 | lock_bar_to(version, 100); |
be28b58b EH |
432 | match run_cargo() { |
433 | Ok(behavior) => { | |
434 | check_lock!(tc_result, "bar", which, behavior.bar, "1.0.0"); | |
435 | check_lock!(tc_result, "baz", which, behavior.baz, None); | |
436 | check_lock!(tc_result, "new-baz-dep", which, behavior.new_baz_dep, None); | |
437 | } | |
438 | Err(e) => { | |
439 | tc_result.push(format!("bar 1.0.0 locked build failed: {}", e)); | |
440 | } | |
441 | } | |
442 | ||
443 | let which = "locked bar 1.0.1"; | |
e58c544f | 444 | lock_bar_to(version, 101); |
be28b58b EH |
445 | match run_cargo() { |
446 | Ok(behavior) => { | |
447 | check_lock!(tc_result, "bar", which, behavior.bar, "1.0.1"); | |
448 | check_lock!(tc_result, "baz", which, behavior.baz, None); | |
449 | check_lock!(tc_result, "new-baz-dep", which, behavior.new_baz_dep, None); | |
450 | } | |
451 | Err(e) => { | |
452 | if toolchain == "this" { | |
453 | // 1.0.1 can't be used without -Znamespaced-features | |
454 | // It gets filtered out of the index. | |
455 | check_err_contains(&mut tc_result, e, | |
456 | "error: failed to select a version for the requirement `bar = \"=1.0.1\"`\n\ | |
457 | candidate versions found which didn't match: 1.0.2, 1.0.0" | |
458 | ); | |
459 | } else { | |
460 | tc_result.push(format!("bar 1.0.1 locked build failed: {}", e)); | |
461 | } | |
462 | } | |
463 | } | |
464 | ||
465 | let which = "locked bar 1.0.2"; | |
e58c544f | 466 | lock_bar_to(version, 102); |
be28b58b EH |
467 | match run_cargo() { |
468 | Ok(behavior) => { | |
469 | check_lock!(tc_result, "bar", which, behavior.bar, "1.0.2"); | |
470 | check_lock!(tc_result, "baz", which, behavior.baz, "1.0.1"); | |
471 | check_lock!(tc_result, "new-baz-dep", which, behavior.new_baz_dep, None); | |
472 | } | |
473 | Err(e) => { | |
474 | if toolchain == "this" { | |
475 | // baz can't lock to 1.0.1, it requires -Znamespaced-features | |
476 | check_err_contains(&mut tc_result, e, | |
477 | "error: failed to select a version for the requirement `baz = \"=1.0.1\"`\n\ | |
478 | candidate versions found which didn't match: 1.0.0" | |
479 | ); | |
480 | } else { | |
481 | tc_result.push(format!("bar 1.0.2 locked build failed: {}", e)); | |
482 | } | |
483 | } | |
484 | } | |
485 | ||
486 | unexpected_results.push(tc_result); | |
487 | } | |
488 | ||
489 | // Generate a report. | |
490 | let mut has_err = false; | |
491 | for ((tc_vers, tc_name), errs) in toolchains.iter().zip(unexpected_results) { | |
492 | if errs.is_empty() { | |
493 | continue; | |
494 | } | |
495 | eprintln!("error: toolchain {} (version {}):", tc_name, tc_vers); | |
496 | for err in errs { | |
497 | eprintln!(" {}", err); | |
498 | } | |
499 | has_err = true; | |
500 | } | |
501 | if has_err { | |
502 | panic!("at least one toolchain did not run as expected"); | |
503 | } | |
504 | } | |
0d4137f4 EH |
505 | |
506 | #[cargo_test] | |
507 | #[ignore] | |
508 | fn index_cache_rebuild() { | |
509 | // Checks that the index cache gets rebuilt. | |
510 | // | |
511 | // 1.48 will not cache entries with features with the same name as a | |
512 | // dependency. If the cache does not get rebuilt, then running with | |
513 | // `-Znamespaced-features` would prevent the new cargo from seeing those | |
514 | // entries. The index cache version was changed to prevent this from | |
515 | // happening, and switching between versions should work correctly | |
516 | // (although it will thrash the cash, that's better than not working | |
517 | // correctly. | |
518 | Package::new("baz", "1.0.0").publish(); | |
519 | Package::new("bar", "1.0.0").publish(); | |
520 | Package::new("bar", "1.0.1") | |
521 | .add_dep(Dependency::new("baz", "1.0").optional(true)) | |
522 | .feature("baz", &["dep:baz"]) | |
523 | .publish(); | |
524 | ||
525 | let p = project() | |
526 | .file( | |
527 | "Cargo.toml", | |
528 | r#" | |
529 | [package] | |
530 | name = "foo" | |
531 | version = "0.1.0" | |
532 | ||
533 | [dependencies] | |
534 | bar = "1.0" | |
535 | "#, | |
536 | ) | |
537 | .file("src/lib.rs", "") | |
538 | .build(); | |
539 | ||
540 | // This version of Cargo errors on index entries that have overlapping | |
541 | // feature names, so 1.0.1 will be missing. | |
542 | execs() | |
543 | .with_process_builder(tc_process("cargo", "1.48.0")) | |
544 | .arg("check") | |
545 | .cwd(p.root()) | |
546 | .with_stderr( | |
547 | "\ | |
548 | [UPDATING] [..] | |
549 | [DOWNLOADING] crates ... | |
550 | [DOWNLOADED] bar v1.0.0 [..] | |
551 | [CHECKING] bar v1.0.0 | |
552 | [CHECKING] foo v0.1.0 [..] | |
553 | [FINISHED] [..] | |
554 | ", | |
555 | ) | |
556 | .run(); | |
557 | ||
558 | fs::remove_file(p.root().join("Cargo.lock")).unwrap(); | |
559 | ||
560 | // This should rebuild the cache and use 1.0.1. | |
43a063c8 | 561 | p.cargo("check") |
0d4137f4 EH |
562 | .with_stderr( |
563 | "\ | |
564 | [UPDATING] [..] | |
565 | [DOWNLOADING] crates ... | |
566 | [DOWNLOADED] bar v1.0.1 [..] | |
567 | [CHECKING] bar v1.0.1 | |
568 | [CHECKING] foo v0.1.0 [..] | |
569 | [FINISHED] [..] | |
570 | ", | |
571 | ) | |
572 | .run(); | |
573 | ||
574 | fs::remove_file(p.root().join("Cargo.lock")).unwrap(); | |
575 | ||
576 | // Verify 1.48 can still resolve, and is at 1.0.0. | |
577 | execs() | |
578 | .with_process_builder(tc_process("cargo", "1.48.0")) | |
579 | .arg("tree") | |
580 | .cwd(p.root()) | |
581 | .with_stdout( | |
582 | "\ | |
583 | foo v0.1.0 [..] | |
584 | └── bar v1.0.0 | |
585 | ", | |
586 | ) | |
587 | .run(); | |
588 | } | |
256c43c2 EH |
589 | |
590 | #[cargo_test] | |
591 | #[ignore] | |
592 | fn avoids_split_debuginfo_collision() { | |
593 | // Checks for a bug where .o files were being incorrectly shared between | |
594 | // different toolchains using incremental and split-debuginfo on macOS. | |
595 | let p = project() | |
596 | .file( | |
597 | "Cargo.toml", | |
598 | r#" | |
599 | [package] | |
600 | name = "foo" | |
601 | version = "0.1.0" | |
602 | ||
603 | [profile.dev] | |
604 | split-debuginfo = "unpacked" | |
605 | "#, | |
606 | ) | |
607 | .file("src/main.rs", "fn main() {}") | |
608 | .build(); | |
609 | ||
610 | execs() | |
611 | .with_process_builder(tc_process("cargo", "stable")) | |
612 | .arg("build") | |
613 | .env("CARGO_INCREMENTAL", "1") | |
614 | .cwd(p.root()) | |
615 | .with_stderr( | |
616 | "\ | |
617 | [COMPILING] foo v0.1.0 [..] | |
618 | [FINISHED] [..] | |
619 | ", | |
620 | ) | |
621 | .run(); | |
622 | ||
623 | p.cargo("build") | |
624 | .env("CARGO_INCREMENTAL", "1") | |
625 | .with_stderr( | |
626 | "\ | |
627 | [COMPILING] foo v0.1.0 [..] | |
628 | [FINISHED] [..] | |
629 | ", | |
630 | ) | |
631 | .run(); | |
632 | ||
633 | execs() | |
634 | .with_process_builder(tc_process("cargo", "stable")) | |
635 | .arg("build") | |
636 | .env("CARGO_INCREMENTAL", "1") | |
637 | .cwd(p.root()) | |
638 | .with_stderr( | |
639 | "\ | |
640 | [COMPILING] foo v0.1.0 [..] | |
641 | [FINISHED] [..] | |
642 | ", | |
643 | ) | |
644 | .run(); | |
645 | } |