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