Skip to content

Commit 908645d

Browse files
committed
Make freshness/rebuilding tests more robust
This commit implements a new heavy handed strategy in the test suite to avoid spurious test failures and improve consistency across platforms. Instead of letting mtimes naturally work as they normally do through out tests we force all executions of `cargo` in the tests to, just before `cargo` is run`, deterministically set all mtime values. This way all executions of `cargo` should see the same mtime and hopefully not be susceptible to drift here and there. Additionally tests now have the ability to say that a file needs to be created (to test mtimes and such). This will whitelist the file as having a new mtime which is known to be a large amount of time in the future (to avoid bugs with fast or slow tests). This way we also know exactly that we can bust caches in tests. Finally, Cargo was outfitted with a new change. Whenever Cargo is tracking mtime data it will latch onto the newest mtime (even if it's in the future) for the output. This is meant to handle two cases: * For tests which have files in the far future it allows subsequent rebuilds to work correctly, otherwise since a test never takes hours it looks like there's always a file modified in the future. * When a file is edited during a build this should ensure that the mtime recorded for the build is the mtime *before* the build starts rather than after the build finishes, ensuring that we correctly schedule builds for edited files. Closes #5940
1 parent 065e3ef commit 908645d

18 files changed

+300
-352
lines changed

tests/testsuite/bench.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use support::is_nightly;
2-
use support::paths::CargoPathExt;
32
use support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project};
43

54
#[test]
@@ -13,22 +12,23 @@ fn cargo_bench_simple() {
1312
.file(
1413
"src/main.rs",
1514
r#"
16-
#![feature(test)]
17-
#[cfg(test)]
18-
extern crate test;
19-
20-
fn hello() -> &'static str {
21-
"hello"
22-
}
23-
24-
pub fn main() {
25-
println!("{}", hello())
26-
}
27-
28-
#[bench]
29-
fn bench_hello(_b: &mut test::Bencher) {
30-
assert_eq!(hello(), "hello")
31-
}"#,
15+
#![feature(test)]
16+
#[cfg(test)]
17+
extern crate test;
18+
19+
fn hello() -> &'static str {
20+
"hello"
21+
}
22+
23+
pub fn main() {
24+
println!("{}", hello())
25+
}
26+
27+
#[bench]
28+
fn bench_hello(_b: &mut test::Bencher) {
29+
assert_eq!(hello(), "hello")
30+
}
31+
"#,
3232
).build();
3333

3434
p.cargo("build").run();
@@ -42,7 +42,8 @@ fn cargo_bench_simple() {
4242
[COMPILING] foo v0.5.0 (CWD)
4343
[FINISHED] release [optimized] target(s) in [..]
4444
[RUNNING] target/release/deps/foo-[..][EXE]",
45-
).with_stdout_contains("test bench_hello ... bench: [..]")
45+
)
46+
.with_stdout_contains("test bench_hello ... bench: [..]")
4647
.run();
4748
}
4849

@@ -844,7 +845,7 @@ fn bench_dylib() {
844845
return;
845846
}
846847

847-
let p = project()
848+
let mut p = project()
848849
.file(
849850
"Cargo.toml",
850851
r#"
@@ -913,7 +914,7 @@ fn bench_dylib() {
913914
).with_stdout_contains_n("test foo ... bench: [..]", 2)
914915
.run();
915916

916-
p.root().move_into_the_past();
917+
p.write_file("foo", "bar");
917918
p.cargo("bench -v")
918919
.with_stderr(
919920
"\

tests/testsuite/build.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use std::env;
22
use std::fs::{self, File};
33
use std::io::prelude::*;
4+
use std::thread;
5+
use std::time::Duration;
46

57
use cargo::util::paths::dylib_path_envvar;
68
use support::paths::{root, CargoPathExt};
79
use support::registry::Package;
810
use support::ProjectBuilder;
911
use support::{
10-
basic_bin_manifest, basic_lib_manifest, basic_manifest, is_nightly, rustc_host, sleep_ms,
12+
basic_bin_manifest, basic_lib_manifest, basic_manifest, is_nightly, rustc_host,
1113
};
1214
use support::{main_file, project, Execs};
1315

@@ -1986,7 +1988,7 @@ fn inferred_main_bin() {
19861988

19871989
#[test]
19881990
fn deletion_causes_failure() {
1989-
let p = project()
1991+
let mut p = project()
19901992
.file(
19911993
"Cargo.toml",
19921994
r#"
@@ -2004,7 +2006,7 @@ fn deletion_causes_failure() {
20042006
.build();
20052007

20062008
p.cargo("build").run();
2007-
p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1"));
2009+
p.write_file("Cargo.toml", &basic_manifest("foo", "0.0.1"));
20082010
p.cargo("build").with_status(101).run();
20092011
}
20102012

@@ -2123,7 +2125,7 @@ fn single_lib() {
21232125

21242126
#[test]
21252127
fn freshness_ignores_excluded() {
2126-
let foo = project()
2128+
let mut foo = project()
21272129
.file(
21282130
"Cargo.toml",
21292131
r#"
@@ -2137,7 +2139,6 @@ fn freshness_ignores_excluded() {
21372139
).file("build.rs", "fn main() {}")
21382140
.file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
21392141
.build();
2140-
foo.root().move_into_the_past();
21412142

21422143
foo.cargo("build")
21432144
.with_stderr(
@@ -2149,17 +2150,17 @@ fn freshness_ignores_excluded() {
21492150

21502151
// Smoke test to make sure it doesn't compile again
21512152
println!("first pass");
2152-
foo.cargo("build").with_stdout("").run();
2153+
foo.cargo("build").with_stderr("[FINISHED] [..]\n").run();
21532154

21542155
// Modify an ignored file and make sure we don't rebuild
21552156
println!("second pass");
2156-
File::create(&foo.root().join("src/bar.rs")).unwrap();
2157-
foo.cargo("build").with_stdout("").run();
2157+
foo.write_file("src/bar.rs", "");
2158+
foo.cargo("build").with_stderr("[FINISHED] [..]\n").run();
21582159
}
21592160

21602161
#[test]
21612162
fn rebuild_preserves_out_dir() {
2162-
let foo = project()
2163+
let mut foo = project()
21632164
.file(
21642165
"Cargo.toml",
21652166
r#"
@@ -2187,7 +2188,6 @@ fn rebuild_preserves_out_dir() {
21872188
"#,
21882189
).file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
21892190
.build();
2190-
foo.root().move_into_the_past();
21912191

21922192
foo.cargo("build")
21932193
.env("FIRST", "1")
@@ -2198,7 +2198,7 @@ fn rebuild_preserves_out_dir() {
21982198
",
21992199
).run();
22002200

2201-
File::create(&foo.root().join("src/bar.rs")).unwrap();
2201+
foo.write_file("src/bar.rs", "");
22022202
foo.cargo("build")
22032203
.with_stderr(
22042204
"\
@@ -2247,8 +2247,7 @@ fn recompile_space_in_name() {
22472247
).file("src/my lib.rs", "")
22482248
.build();
22492249
foo.cargo("build").run();
2250-
foo.root().move_into_the_past();
2251-
foo.cargo("build").with_stdout("").run();
2250+
foo.cargo("build").with_stderr("[FINISHED] [..]\n").run();
22522251
}
22532252

22542253
#[cfg(unix)]
@@ -2524,7 +2523,7 @@ fn compile_then_delete() {
25242523
assert!(p.bin("foo").is_file());
25252524
if cfg!(windows) {
25262525
// On windows unlinking immediately after running often fails, so sleep
2527-
sleep_ms(100);
2526+
thread::sleep(Duration::from_millis(100));
25282527
}
25292528
fs::remove_file(&p.bin("foo")).unwrap();
25302529
p.cargo("run -v").run();

0 commit comments

Comments
 (0)