mirror of
https://github.com/Momoko-Ayase/Senbei.git
synced 2026-11-04 10:31:29 -05:00
69 lines
2.4 KiB
Rust
69 lines
2.4 KiB
Rust
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
use std::sync::{Arc, Barrier};
|
|
|
|
#[test]
|
|
fn folder_runs_preserve_the_host_panic_hook() {
|
|
const CHILD: &str = "SENBEI_PANIC_HOOK_TEST_CHILD";
|
|
if std::env::var_os(CHILD).is_none() {
|
|
let output = std::process::Command::new(std::env::current_exe().unwrap())
|
|
.args([
|
|
"--exact",
|
|
"folder_runs_preserve_the_host_panic_hook",
|
|
"--nocapture",
|
|
])
|
|
.env(CHILD, "1")
|
|
.output()
|
|
.unwrap();
|
|
assert!(
|
|
output.status.success(),
|
|
"child failed: {}\n{}",
|
|
String::from_utf8_lossy(&output.stdout),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
return;
|
|
}
|
|
|
|
static CALLS: AtomicUsize = AtomicUsize::new(0);
|
|
std::panic::set_hook(Box::new(|_| {
|
|
CALLS.fetch_add(1, Ordering::SeqCst);
|
|
}));
|
|
let root = tempfile::tempdir().unwrap();
|
|
// Exercise repeated job lifetimes both before and after engine capture.
|
|
for _ in 0..2 {
|
|
senbei_io::job::run_folder_opts(root.path(), None, 2, false, true, false).unwrap();
|
|
assert!(senbei_engine::catch_unwind_quiet(|| panic!("captured")).is_err());
|
|
assert!(std::panic::catch_unwind(|| panic!("host")).is_err());
|
|
}
|
|
assert_eq!(CALLS.load(Ordering::SeqCst), 2);
|
|
|
|
let barrier = Arc::new(Barrier::new(2));
|
|
let worker_barrier = barrier.clone();
|
|
let worker = std::thread::spawn(move || {
|
|
senbei_engine::catch_unwind_quiet(|| {
|
|
worker_barrier.wait();
|
|
worker_barrier.wait();
|
|
panic!("captured in another thread");
|
|
})
|
|
.unwrap_err();
|
|
});
|
|
barrier.wait();
|
|
// A quiet capture in another thread must not silence unrelated panics.
|
|
assert!(std::panic::catch_unwind(|| panic!("unrelated host panic")).is_err());
|
|
barrier.wait();
|
|
worker.join().unwrap();
|
|
assert_eq!(CALLS.load(Ordering::SeqCst), 3);
|
|
|
|
std::thread::scope(|scope| {
|
|
for _ in 0..4 {
|
|
let path = root.path();
|
|
scope.spawn(move || {
|
|
senbei_io::job::run_folder_opts(path, None, 2, false, true, false).unwrap();
|
|
assert!(
|
|
senbei_engine::catch_unwind_quiet(|| panic!("after concurrent job")).is_err()
|
|
);
|
|
});
|
|
}
|
|
});
|
|
assert_eq!(CALLS.load(Ordering::SeqCst), 3);
|
|
}
|