1 #![cfg(feature = "sync")]
2 
3 #[cfg(target_arch = "wasm32")]
4 use wasm_bindgen_test::wasm_bindgen_test as test;
5 
6 use std::sync::Arc;
7 use tokio::sync::Semaphore;
8 
9 #[test]
no_permits()10 fn no_permits() {
11     // this should not panic
12     Semaphore::new(0);
13 }
14 
15 #[test]
try_acquire()16 fn try_acquire() {
17     let sem = Semaphore::new(1);
18     {
19         let p1 = sem.try_acquire();
20         assert!(p1.is_ok());
21         let p2 = sem.try_acquire();
22         assert!(p2.is_err());
23     }
24     let p3 = sem.try_acquire();
25     assert!(p3.is_ok());
26 }
27 
28 #[tokio::test]
29 #[cfg(feature = "full")]
acquire()30 async fn acquire() {
31     let sem = Arc::new(Semaphore::new(1));
32     let p1 = sem.try_acquire().unwrap();
33     let sem_clone = sem.clone();
34     let j = tokio::spawn(async move {
35         let _p2 = sem_clone.acquire().await;
36     });
37     drop(p1);
38     j.await.unwrap();
39 }
40 
41 #[tokio::test]
42 #[cfg(feature = "full")]
add_permits()43 async fn add_permits() {
44     let sem = Arc::new(Semaphore::new(0));
45     let sem_clone = sem.clone();
46     let j = tokio::spawn(async move {
47         let _p2 = sem_clone.acquire().await;
48     });
49     sem.add_permits(1);
50     j.await.unwrap();
51 }
52 
53 #[test]
forget()54 fn forget() {
55     let sem = Arc::new(Semaphore::new(1));
56     {
57         let p = sem.try_acquire().unwrap();
58         assert_eq!(sem.available_permits(), 0);
59         p.forget();
60         assert_eq!(sem.available_permits(), 0);
61     }
62     assert_eq!(sem.available_permits(), 0);
63     assert!(sem.try_acquire().is_err());
64 }
65 
66 #[tokio::test]
67 #[cfg(feature = "full")]
stresstest()68 async fn stresstest() {
69     let sem = Arc::new(Semaphore::new(5));
70     let mut join_handles = Vec::new();
71     for _ in 0..1000 {
72         let sem_clone = sem.clone();
73         join_handles.push(tokio::spawn(async move {
74             let _p = sem_clone.acquire().await;
75         }));
76     }
77     for j in join_handles {
78         j.await.unwrap();
79     }
80     // there should be exactly 5 semaphores available now
81     let _p1 = sem.try_acquire().unwrap();
82     let _p2 = sem.try_acquire().unwrap();
83     let _p3 = sem.try_acquire().unwrap();
84     let _p4 = sem.try_acquire().unwrap();
85     let _p5 = sem.try_acquire().unwrap();
86     assert!(sem.try_acquire().is_err());
87 }
88 
89 #[test]
add_max_amount_permits()90 fn add_max_amount_permits() {
91     let s = tokio::sync::Semaphore::new(0);
92     s.add_permits(usize::MAX >> 3);
93     assert_eq!(s.available_permits(), usize::MAX >> 3);
94 }
95 
96 #[cfg(not(target_arch = "wasm32"))] // wasm currently doesn't support unwinding
97 #[test]
98 #[should_panic]
add_more_than_max_amount_permits()99 fn add_more_than_max_amount_permits() {
100     let s = tokio::sync::Semaphore::new(1);
101     s.add_permits(usize::MAX >> 3);
102 }
103