-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make freshness/rebuilding tests more robust #5953
Conversation
r? @matklad (rust_highfive has picked a reviewer for you, use r? to override) |
Cool! Sounds like this fixes #2426. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a couple of questions, the one about the output changing in path::deep_dependencies_trigger_rebuild
being the most important one, which is also the only test that failed on Travis CI. On AppVeyor only 17 test failures!
Overall this looks great to me, thanks!
tests/testsuite/path.rs
Outdated
p.cargo("build") | ||
.with_stderr(&format!( | ||
"[COMPILING] baz v0.5.0 (CWD/baz)\n\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come these outputs changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops! I think I messed something up, wasn't intended to change
tests/testsuite/support/mod.rs
Outdated
@@ -202,6 +204,9 @@ impl SymlinkBuilder { | |||
|
|||
pub struct Project { | |||
root: PathBuf, | |||
start: FileTime, | |||
updates: HashMap<PathBuf, FileTime>, | |||
next_update: i64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it's worth documenting these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops yes, meant to do that already!
tests/testsuite/support/mod.rs
Outdated
|
||
pub fn move_start_back_one_second(&mut self) { | ||
self.start = FileTime::from_unix_time( | ||
self.start.unix_seconds(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a "one second" part missing here? Or am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, my bad!
filetime::set_file_times(&path, time_to_set, time_to_set)?; | ||
MtimeState::LatestTimeIs(time_to_set) | ||
} | ||
_ => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of general, but I tend to avoid using default cases on sum types because if that algebra every changes (in this case, say an OlderThanOrEqual
case is added) it's easy to miss changing these code paths because the exhaustivity checker won't tell you.
In short I'd use
MtimeState::LatestTimeIs(_) | NotAvailable => {
here instead.
Good practice or YAGNI? 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me!
It looks like it is mostly fixed. It doesn't handle files being modified during the first build. This is because the fingerprint starts out with |
There's a problem with it always rebuilding. Example:
I'm not entirely sure at this point how to fix, but it looks like the problem is that when the Fingerprint is first created it contains an |
47a4c3f
to
c544a9f
Compare
@ehuss oh good points! I don't think this'll close #2426 yet. I was also hoping to not touch Cargo at all in this change. One possibility is to just avoid touching the two tests that require the changes to Cargo (one is the deep dependencies test). It'd be a bit of a bummer though to not change those tests which have been flaky! In any case I'll look into the bug when I get a chance and see if the fix is too invasive of if it's just a typo. |
☔ The latest upstream changes (presumably #5966) made this pull request unmergeable. Please resolve the merge conflicts. |
c544a9f
to
0c90b7c
Compare
Ok I think that the changes to Cargo itself probably won't work at this time. There's only two tests which break with the mtime management added here to the test suite, so I've left the sleeps in there and added a method to disable mtime management. This should now hopefully be green and have at least no functional change to Cargo itself! r? @ehuss |
☔ The latest upstream changes (presumably #5976) made this pull request unmergeable. Please resolve the merge conflicts. |
I tried testing the latest commit a little, and I'm still running into a lot of errors. Out of 10 runs, I got the following errors: Error list
For example, it looks like |
@ehuss do you know what the problems are? I don't know why you're seeing so many errors when I never see any myself |
Perhaps ehuss isn't using APFS? |
Correct, this only happens on HFS. APFS has sub-second timestamps. Here's some examples from a few of them: rustc_fingerprintstart mtime = N
deep_dependencies_trigger_rebuildSee #5952 (comment) custom_target_no_rebuildstart mtime = N
no_rebuild_transitive_target_depsstart mtime = N
|
Hm ok, makes sense! Thinking about it I think the original change I had here with modifying Cargo's own concept of mtime is fundamentally required for 1-second resolution filesystems to run the test suite, otherwise everything is just horribly broken. I'll look into fixing it again. |
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 rust-lang#5940
0c90b7c
to
908645d
Compare
Hm so I still don't quite understand how this is causing problems. I just ran |
I'm basically at a loss of what to do. I have no idea how to solve this in a way that doesn't involve overhauling everything which supports all the filesystems and all the way up to one second resolution. If no one else can think of a great way to solve this I'll just close this in the next few days. |
🙁
The |
Ah yeah definitely feel free to! I think I'll actually go ahead and close. |
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 beforecargo
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