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