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