mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-24 09:57:08 -06:00
Merge PR #8473: test(panic_hunt): give the panic-counting self-test its own deadline
This commit is contained in:
@@ -30,9 +30,14 @@ static PANICS: AtomicUsize = AtomicUsize::new(0);
|
||||
/// One run at a time, so a panic is charged to the run that caused it.
|
||||
static RUN: Mutex<()> = Mutex::new(());
|
||||
|
||||
/// Run `f` on a worker thread. `None` if it timed out, else whether it finished without
|
||||
/// panicking, contained or not (returning Ok or a graceful Err both count).
|
||||
fn run_watched(f: impl FnOnce() + Send + 'static) -> Option<bool> {
|
||||
/// Budget for the self-test below, which checks how panics are counted, not hangs. The panic hook
|
||||
/// prints a backtrace under `RUST_BACKTRACE=1` (as in CI), and on a loaded Windows runner the
|
||||
/// first symbol lookup alone can take 15–20 s.
|
||||
const SELF_TEST_DEADLINE: Duration = Duration::from_secs(120);
|
||||
|
||||
/// Run `f` on a worker thread. `None` if it took longer than `deadline`, else whether it
|
||||
/// finished without panicking, contained or not (returning Ok or a graceful Err both count).
|
||||
fn run_watched(deadline: Duration, f: impl FnOnce() + Send + 'static) -> Option<bool> {
|
||||
static HOOK: Once = Once::new();
|
||||
HOOK.call_once(|| {
|
||||
let default = std::panic::take_hook();
|
||||
@@ -48,13 +53,13 @@ fn run_watched(f: impl FnOnce() + Send + 'static) -> Option<bool> {
|
||||
let r = catch_unwind(AssertUnwindSafe(f));
|
||||
let _ = tx.send(r.is_ok());
|
||||
});
|
||||
rx.recv_timeout(DEADLINE).ok().map(|ok| ok && PANICS.load(Ordering::SeqCst) == before)
|
||||
rx.recv_timeout(deadline).ok().map(|ok| ok && PANICS.load(Ordering::SeqCst) == before)
|
||||
}
|
||||
|
||||
/// Run `id` with `p` on a fresh session; see [`run_watched`].
|
||||
fn run_once(id: &str, p: &Value) -> Option<bool> {
|
||||
let (id, p) = (id.to_string(), p.clone());
|
||||
run_watched(move || {
|
||||
run_watched(DEADLINE, move || {
|
||||
let mut s = fresh();
|
||||
let _ = s.execute(&id, p);
|
||||
})
|
||||
@@ -107,11 +112,11 @@ fn no_command_panics_or_hangs_on_adversarial_params() {
|
||||
/// #4982: a panic the code under test contains still fails the run; a graceful `Err` does not.
|
||||
#[test]
|
||||
fn contained_panics_count_and_graceful_errors_do_not() {
|
||||
let contained = run_watched(|| {
|
||||
let contained = run_watched(SELF_TEST_DEADLINE, || {
|
||||
let _ = catch_unwind(|| panic!("contained, as Session::execute does"));
|
||||
});
|
||||
assert_eq!(contained, Some(false));
|
||||
let graceful = run_watched(|| {
|
||||
let graceful = run_watched(SELF_TEST_DEADLINE, || {
|
||||
let mut s = fresh();
|
||||
assert!(s.execute("layer.delete", json!({"layer": 999999})).is_err());
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user