From c99b3a52f25610582318025d6bef5475a16bc2d0 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sat, 9 Dec 2023 14:37:38 -0700 Subject: [PATCH] Less Mutex poisoning If a test case panics while holding a static method's internal Mutex locked, for example by violating a times() constraint, then clear the Mutex's poison during Drop. We're going to delete all of its Expectations anyway, so there's no data to be poisoned. Requires nightly. Fixes #515 --- CHANGELOG.md | 4 ++++ mockall/tests/clear_expectations_on_panic.rs | 2 +- mockall_derive/src/mock_function.rs | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e34f75c..5a19652 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed +- No longer poison a Context object's internal `Mutex` when panicing. This + requires the "nightly" feature. + ([#527](https://github.com/asomers/mockall/pull/527)) + - Raised predicates, which is reexported, to 3.0.0. This may affect backwards compatibility for users who make use of predicates's "color" feature. ([#467](https://github.com/asomers/mockall/pull/467)) diff --git a/mockall/tests/clear_expectations_on_panic.rs b/mockall/tests/clear_expectations_on_panic.rs index 44a8d3f..a70df15 100644 --- a/mockall/tests/clear_expectations_on_panic.rs +++ b/mockall/tests/clear_expectations_on_panic.rs @@ -34,7 +34,7 @@ fn too_few_calls() { // We shouldn't panic during drop in this case. Regression test for // https://github.com/asomers/mockall/issues/491 -#[should_panic(expected = "called `Result::unwrap()` on an `Err` value: PoisonError { .. }")] +#[cfg_attr(not(feature = "nightly"), ignore)] #[test] fn too_many_calls() { panic::catch_unwind(|| { diff --git a/mockall_derive/src/mock_function.rs b/mockall_derive/src/mock_function.rs index 86e45e6..296e9c5 100644 --- a/mockall_derive/src/mock_function.rs +++ b/mockall_derive/src/mock_function.rs @@ -1547,6 +1547,11 @@ impl<'a> ToTokens for Context<'a> { #[cfg(feature = "nightly_derive")] let must_use = quote!(); + #[cfg(not(feature = "nightly_derive"))] + let clear_poison = quote!(); + #[cfg(feature = "nightly_derive")] + let clear_poison = quote!(EXPECTATIONS.clear_poison();); + quote!( /// Manages the context for expectations of static methods. /// @@ -1594,6 +1599,9 @@ impl<'a> ToTokens for Context<'a> { impl #ty_ig Drop for Context #ty_tg #ty_wc { fn drop(&mut self) { if ::std::thread::panicking() { + // Clear poison since we're about to clear the Mutex's + // contents anyway. + #clear_poison // Drain all expectations so other tests can run with a // blank slate. But ignore errors so we don't // double-panic.