drumbeat/utils/
testing.rs1use std::{sync::mpsc, thread, time::Duration};
2
3pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5);
4
5pub fn panic_after<T, F>(d: Duration, f: F) -> T
6where
7 T: Send + 'static,
8 F: FnOnce() -> T + Send + 'static,
9{
10 let (done_tx, done_rx) = mpsc::channel();
11 let handle = thread::Builder::new()
12 .name("testing-thread".to_owned())
13 .spawn(move || {
14 let val = f();
15 done_tx.send(()).expect("failed to send complete signal");
16 val
17 })
18 .unwrap();
19 match done_rx.recv_timeout(d) {
20 Ok(_) => handle.join().expect("thread panicked"),
21 Err(error) => match error {
22 mpsc::RecvTimeoutError::Timeout => panic!("thread took too long"),
23 mpsc::RecvTimeoutError::Disconnected => panic!("thread panicked"),
24 },
25 }
26}
27
28pub fn async_context<T, F>(f: F) -> T
29where
30 T: Send + 'static,
31 F: FnOnce() -> T + Send + 'static,
32{
33 panic_after(DEFAULT_TIMEOUT, f)
34}
35
36pub fn interrupt_after<T, F>(d: Duration, f: F) -> T
37where
38 T: Send + 'static,
39 F: FnOnce() -> T + Send + 'static,
40{
41 let (done_tx, done_rx) = mpsc::channel();
42 let handle = thread::Builder::new()
43 .name("testing-thread".to_owned())
44 .spawn(move || {
45 let val = f();
46 let _ = done_tx.send(());
47 val
48 })
49 .unwrap();
50 let _ = done_rx.recv_timeout(d);
51 handle.join().expect("thread panicked")
52}
53
54pub fn async_panic_context<T, F>(f: F) -> T
55where
56 T: Send + 'static,
57 F: FnOnce() -> T + Send + 'static,
58{
59 interrupt_after(DEFAULT_TIMEOUT, f)
60}
61
62#[cfg(test)]
63mod test {
64 use super::*;
65
66 #[test]
67 #[should_panic]
68 fn panic_after_timeout_test() {
69 panic_after(Duration::from_secs(0), || {
70 std::thread::sleep(Duration::from_secs(1));
71 });
72 }
73
74 #[test]
75 fn no_panic_after_timeout_test() {
76 interrupt_after(Duration::from_secs(0), || {
77 std::thread::sleep(Duration::from_secs(1));
78 });
79 }
80
81 #[test]
82 #[should_panic]
83 fn interrupt_panic_passthrough_test() {
84 interrupt_after(Duration::from_secs(1), || {
85 panic!("test");
86 });
87 }
88}