• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![warn(rust_2018_idioms)]
2 #![cfg(all(feature = "full", not(target_os = "wasi")))]
3 
4 use std::{error::Error, sync::Arc};
5 use tokio::{
6     runtime::{Builder, Runtime},
7     sync::{broadcast, mpsc, oneshot, Mutex, RwLock, Semaphore},
8 };
9 
10 mod support {
11     pub mod panic;
12 }
13 use support::panic::test_panic;
14 
15 #[test]
broadcast_channel_panic_caller() -> Result<(), Box<dyn Error>>16 fn broadcast_channel_panic_caller() -> Result<(), Box<dyn Error>> {
17     let panic_location_file = test_panic(|| {
18         let (_, _) = broadcast::channel::<u32>(0);
19     });
20 
21     // The panic location should be in this file
22     assert_eq!(&panic_location_file.unwrap(), file!());
23 
24     Ok(())
25 }
26 
27 #[test]
mutex_blocking_lock_panic_caller() -> Result<(), Box<dyn Error>>28 fn mutex_blocking_lock_panic_caller() -> Result<(), Box<dyn Error>> {
29     let panic_location_file = test_panic(|| {
30         let rt = current_thread();
31         rt.block_on(async {
32             let mutex = Mutex::new(5_u32);
33             let _g = mutex.blocking_lock();
34         });
35     });
36 
37     // The panic location should be in this file
38     assert_eq!(&panic_location_file.unwrap(), file!());
39 
40     Ok(())
41 }
42 
43 #[test]
oneshot_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>>44 fn oneshot_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>> {
45     let panic_location_file = test_panic(|| {
46         let rt = current_thread();
47         rt.block_on(async {
48             let (_tx, rx) = oneshot::channel::<u8>();
49             let _ = rx.blocking_recv();
50         });
51     });
52 
53     // The panic location should be in this file
54     assert_eq!(&panic_location_file.unwrap(), file!());
55 
56     Ok(())
57 }
58 
59 #[test]
rwlock_with_max_readers_panic_caller() -> Result<(), Box<dyn Error>>60 fn rwlock_with_max_readers_panic_caller() -> Result<(), Box<dyn Error>> {
61     let panic_location_file = test_panic(|| {
62         let _ = RwLock::<u8>::with_max_readers(0, (u32::MAX >> 3) + 1);
63     });
64 
65     // The panic location should be in this file
66     assert_eq!(&panic_location_file.unwrap(), file!());
67 
68     Ok(())
69 }
70 
71 #[test]
rwlock_blocking_read_panic_caller() -> Result<(), Box<dyn Error>>72 fn rwlock_blocking_read_panic_caller() -> Result<(), Box<dyn Error>> {
73     let panic_location_file = test_panic(|| {
74         let rt = current_thread();
75         rt.block_on(async {
76             let lock = RwLock::<u8>::new(0);
77             let _ = lock.blocking_read();
78         });
79     });
80 
81     // The panic location should be in this file
82     assert_eq!(&panic_location_file.unwrap(), file!());
83 
84     Ok(())
85 }
86 
87 #[test]
rwlock_blocking_write_panic_caller() -> Result<(), Box<dyn Error>>88 fn rwlock_blocking_write_panic_caller() -> Result<(), Box<dyn Error>> {
89     let panic_location_file = test_panic(|| {
90         let rt = current_thread();
91         rt.block_on(async {
92             let lock = RwLock::<u8>::new(0);
93             let _ = lock.blocking_write();
94         });
95     });
96 
97     // The panic location should be in this file
98     assert_eq!(&panic_location_file.unwrap(), file!());
99 
100     Ok(())
101 }
102 
103 #[test]
mpsc_bounded_channel_panic_caller() -> Result<(), Box<dyn Error>>104 fn mpsc_bounded_channel_panic_caller() -> Result<(), Box<dyn Error>> {
105     let panic_location_file = test_panic(|| {
106         let (_, _) = mpsc::channel::<u8>(0);
107     });
108 
109     // The panic location should be in this file
110     assert_eq!(&panic_location_file.unwrap(), file!());
111 
112     Ok(())
113 }
114 
115 #[test]
mpsc_bounded_receiver_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>>116 fn mpsc_bounded_receiver_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>> {
117     let panic_location_file = test_panic(|| {
118         let rt = current_thread();
119         let (_tx, mut rx) = mpsc::channel::<u8>(1);
120         rt.block_on(async {
121             let _ = rx.blocking_recv();
122         });
123     });
124 
125     // The panic location should be in this file
126     assert_eq!(&panic_location_file.unwrap(), file!());
127 
128     Ok(())
129 }
130 
131 #[test]
mpsc_bounded_sender_blocking_send_panic_caller() -> Result<(), Box<dyn Error>>132 fn mpsc_bounded_sender_blocking_send_panic_caller() -> Result<(), Box<dyn Error>> {
133     let panic_location_file = test_panic(|| {
134         let rt = current_thread();
135         let (tx, _rx) = mpsc::channel::<u8>(1);
136         rt.block_on(async {
137             let _ = tx.blocking_send(3);
138         });
139     });
140 
141     // The panic location should be in this file
142     assert_eq!(&panic_location_file.unwrap(), file!());
143 
144     Ok(())
145 }
146 
147 #[test]
mpsc_unbounded_receiver_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>>148 fn mpsc_unbounded_receiver_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>> {
149     let panic_location_file = test_panic(|| {
150         let rt = current_thread();
151         let (_tx, mut rx) = mpsc::unbounded_channel::<u8>();
152         rt.block_on(async {
153             let _ = rx.blocking_recv();
154         });
155     });
156 
157     // The panic location should be in this file
158     assert_eq!(&panic_location_file.unwrap(), file!());
159 
160     Ok(())
161 }
162 
163 #[test]
semaphore_merge_unrelated_owned_permits() -> Result<(), Box<dyn Error>>164 fn semaphore_merge_unrelated_owned_permits() -> Result<(), Box<dyn Error>> {
165     let panic_location_file = test_panic(|| {
166         let sem1 = Arc::new(Semaphore::new(42));
167         let sem2 = Arc::new(Semaphore::new(42));
168         let mut p1 = sem1.try_acquire_owned().unwrap();
169         let p2 = sem2.try_acquire_owned().unwrap();
170         p1.merge(p2);
171     });
172 
173     // The panic location should be in this file
174     assert_eq!(&panic_location_file.unwrap(), file!());
175 
176     Ok(())
177 }
178 
179 #[test]
semaphore_merge_unrelated_permits() -> Result<(), Box<dyn Error>>180 fn semaphore_merge_unrelated_permits() -> Result<(), Box<dyn Error>> {
181     let panic_location_file = test_panic(|| {
182         let sem1 = Semaphore::new(42);
183         let sem2 = Semaphore::new(42);
184         let mut p1 = sem1.try_acquire().unwrap();
185         let p2 = sem2.try_acquire().unwrap();
186         p1.merge(p2);
187     });
188 
189     // The panic location should be in this file
190     assert_eq!(&panic_location_file.unwrap(), file!());
191 
192     Ok(())
193 }
194 
current_thread() -> Runtime195 fn current_thread() -> Runtime {
196     Builder::new_current_thread().enable_all().build().unwrap()
197 }
198