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