1 #![warn(rust_2018_idioms)]
2 #![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support panic recovery
3 #![cfg(panic = "unwind")]
4 
5 use futures::future;
6 use std::error::Error;
7 use std::time::Duration;
8 use tokio::runtime::{Builder, Runtime};
9 use tokio::time::{self, interval, interval_at, timeout, Instant};
10 
11 mod support {
12     pub mod panic;
13 }
14 use support::panic::test_panic;
15 
16 #[test]
pause_panic_caller() -> Result<(), Box<dyn Error>>17 fn pause_panic_caller() -> Result<(), Box<dyn Error>> {
18     let panic_location_file = test_panic(|| {
19         let rt = current_thread();
20 
21         rt.block_on(async {
22             time::pause();
23             time::pause();
24         });
25     });
26 
27     // The panic location should be in this file
28     assert_eq!(&panic_location_file.unwrap(), file!());
29 
30     Ok(())
31 }
32 
33 #[test]
resume_panic_caller() -> Result<(), Box<dyn Error>>34 fn resume_panic_caller() -> Result<(), Box<dyn Error>> {
35     let panic_location_file = test_panic(|| {
36         let rt = current_thread();
37 
38         rt.block_on(async {
39             time::resume();
40         });
41     });
42 
43     // The panic location should be in this file
44     assert_eq!(&panic_location_file.unwrap(), file!());
45 
46     Ok(())
47 }
48 
49 #[test]
interval_panic_caller() -> Result<(), Box<dyn Error>>50 fn interval_panic_caller() -> Result<(), Box<dyn Error>> {
51     let panic_location_file = test_panic(|| {
52         let _ = interval(Duration::from_millis(0));
53     });
54 
55     // The panic location should be in this file
56     assert_eq!(&panic_location_file.unwrap(), file!());
57 
58     Ok(())
59 }
60 
61 #[test]
interval_at_panic_caller() -> Result<(), Box<dyn Error>>62 fn interval_at_panic_caller() -> Result<(), Box<dyn Error>> {
63     let panic_location_file = test_panic(|| {
64         let _ = interval_at(Instant::now(), Duration::from_millis(0));
65     });
66 
67     // The panic location should be in this file
68     assert_eq!(&panic_location_file.unwrap(), file!());
69 
70     Ok(())
71 }
72 
73 #[test]
timeout_panic_caller() -> Result<(), Box<dyn Error>>74 fn timeout_panic_caller() -> Result<(), Box<dyn Error>> {
75     let panic_location_file = test_panic(|| {
76         // Runtime without `enable_time` so it has no current timer set.
77         let rt = Builder::new_current_thread().build().unwrap();
78         rt.block_on(async {
79             let _timeout = timeout(Duration::from_millis(5), future::pending::<()>());
80         });
81     });
82 
83     // The panic location should be in this file
84     assert_eq!(&panic_location_file.unwrap(), file!());
85 
86     Ok(())
87 }
88 
current_thread() -> Runtime89 fn current_thread() -> Runtime {
90     tokio::runtime::Builder::new_current_thread()
91         .enable_all()
92         .build()
93         .unwrap()
94 }
95