Fix #[after] not running when tests are ignored or filtered - #2
Merged
Merged
Conversation
The `after` hook fired via an atomic countdown seeded with the number of tests in the group. Any test the harness didn't run (#[ignore], #[cfg], a name filter, or --skip) never decremented the counter, so it never hit zero and `after` never ran. Teardown was silently skipped and resources leaked (issue #1). Counting can't fix this: which tests run is decided at runtime by libtest, not at expansion time. Instead, register the group's `after` as a teardown that runs once at process exit, guarded by a Once so it registers on the first test that runs. It fires exactly once as long as any test in the group ran, regardless of filtering. Applies to both #[test_suite] and spec!.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1.
#[after]used an atomic countdown to spot the last test in a group. The counter started at the number of tests and each test decremented it on the way out. Trouble is, a test that's#[ignore]d or#[cfg]'d out never runs, so it never decrements, the counter stays above zero, andafternever fires. Your teardown gets skipped and containers leak.It's actually broader than ignored tests. Any time the harness runs a subset, a name filter like
cargo test some_nameor--skip, the count is wrong andaftergoes missing. Counting can't win, because which tests run is a runtime decision libtest makes, not something the macro can see when it expands.So this drops the countdown. The first test in a group to run registers the group's
afteras a teardown, and it runs once at process exit through a Catexithandler. It fires exactly once as long as at least one test in the group ran, no matter how the run got filtered. Covers both#[test_suite]andspec!.The regression test re-execs the test binary with a single-test filter and checks the teardown still ran.
A few things worth knowing:
afterruns once per test instead of once per group. The old countdown was broken there anyway, so this is still a step up.afterwon't run. No in-process hook can help with that.