1 #![cfg(feature = "sync")]
2 
3 #[cfg(all(target_family = "wasm", not(target_os = "wasi")))]
4 use wasm_bindgen_test::wasm_bindgen_test as test;
5 
6 use std::sync::Arc;
7 use tokio::sync::Semaphore;
8 
9 #[test]
try_acquire()10 fn try_acquire() {
11     let sem = Arc::new(Semaphore::new(1));
12     {
13         let p1 = sem.clone().try_acquire_owned();
14         assert!(p1.is_ok());
15         let p2 = sem.clone().try_acquire_owned();
16         assert!(p2.is_err());
17     }
18     let p3 = sem.try_acquire_owned();
19     assert!(p3.is_ok());
20 }
21 
22 #[test]
try_acquire_many()23 fn try_acquire_many() {
24     let sem = Arc::new(Semaphore::new(42));
25     {
26         let p1 = sem.clone().try_acquire_many_owned(42);
27         assert!(p1.is_ok());
28         let p2 = sem.clone().try_acquire_owned();
29         assert!(p2.is_err());
30     }
31     let p3 = sem.clone().try_acquire_many_owned(32);
32     assert!(p3.is_ok());
33     let p4 = sem.clone().try_acquire_many_owned(10);
34     assert!(p4.is_ok());
35     assert!(sem.try_acquire_owned().is_err());
36 }
37 
38 #[tokio::test]
39 #[cfg(feature = "full")]
acquire()40 async fn acquire() {
41     let sem = Arc::new(Semaphore::new(1));
42     let p1 = sem.clone().try_acquire_owned().unwrap();
43     let sem_clone = sem.clone();
44     let j = tokio::spawn(async move {
45         let _p2 = sem_clone.acquire_owned().await;
46     });
47     drop(p1);
48     j.await.unwrap();
49 }
50 
51 #[tokio::test]
52 #[cfg(feature = "full")]
acquire_many()53 async fn acquire_many() {
54     let semaphore = Arc::new(Semaphore::new(42));
55     let permit32 = semaphore.clone().try_acquire_many_owned(32).unwrap();
56     let (sender, receiver) = tokio::sync::oneshot::channel();
57     let join_handle = tokio::spawn(async move {
58         let _permit10 = semaphore.clone().acquire_many_owned(10).await.unwrap();
59         sender.send(()).unwrap();
60         let _permit32 = semaphore.acquire_many_owned(32).await.unwrap();
61     });
62     receiver.await.unwrap();
63     drop(permit32);
64     join_handle.await.unwrap();
65 }
66 
67 #[tokio::test]
68 #[cfg(feature = "full")]
add_permits()69 async fn add_permits() {
70     let sem = Arc::new(Semaphore::new(0));
71     let sem_clone = sem.clone();
72     let j = tokio::spawn(async move {
73         let _p2 = sem_clone.acquire_owned().await;
74     });
75     sem.add_permits(1);
76     j.await.unwrap();
77 }
78 
79 #[test]
forget()80 fn forget() {
81     let sem = Arc::new(Semaphore::new(1));
82     {
83         let p = sem.clone().try_acquire_owned().unwrap();
84         assert_eq!(sem.available_permits(), 0);
85         p.forget();
86         assert_eq!(sem.available_permits(), 0);
87     }
88     assert_eq!(sem.available_permits(), 0);
89     assert!(sem.try_acquire_owned().is_err());
90 }
91 
92 #[test]
merge()93 fn merge() {
94     let sem = Arc::new(Semaphore::new(3));
95     {
96         let mut p1 = sem.clone().try_acquire_owned().unwrap();
97         assert_eq!(sem.available_permits(), 2);
98         let p2 = sem.clone().try_acquire_many_owned(2).unwrap();
99         assert_eq!(sem.available_permits(), 0);
100         p1.merge(p2);
101         assert_eq!(sem.available_permits(), 0);
102     }
103     assert_eq!(sem.available_permits(), 3);
104 }
105 
106 #[test]
107 #[cfg(not(target_family = "wasm"))] // No stack unwinding on wasm targets
108 #[should_panic]
merge_unrelated_permits()109 fn merge_unrelated_permits() {
110     let sem1 = Arc::new(Semaphore::new(3));
111     let sem2 = Arc::new(Semaphore::new(3));
112     let mut p1 = sem1.try_acquire_owned().unwrap();
113     let p2 = sem2.try_acquire_owned().unwrap();
114     p1.merge(p2)
115 }
116 
117 #[test]
split()118 fn split() {
119     let sem = Arc::new(Semaphore::new(5));
120     let mut p1 = sem.clone().try_acquire_many_owned(3).unwrap();
121     assert_eq!(sem.available_permits(), 2);
122     assert_eq!(p1.num_permits(), 3);
123     let mut p2 = p1.split(1).unwrap();
124     assert_eq!(sem.available_permits(), 2);
125     assert_eq!(p1.num_permits(), 2);
126     assert_eq!(p2.num_permits(), 1);
127     let p3 = p1.split(0).unwrap();
128     assert_eq!(p3.num_permits(), 0);
129     drop(p1);
130     assert_eq!(sem.available_permits(), 4);
131     let p4 = p2.split(1).unwrap();
132     assert_eq!(p2.num_permits(), 0);
133     assert_eq!(p4.num_permits(), 1);
134     assert!(p2.split(1).is_none());
135     drop(p2);
136     assert_eq!(sem.available_permits(), 4);
137     drop(p3);
138     assert_eq!(sem.available_permits(), 4);
139     drop(p4);
140     assert_eq!(sem.available_permits(), 5);
141 }
142 
143 #[tokio::test]
144 #[cfg(feature = "full")]
stress_test()145 async fn stress_test() {
146     let sem = Arc::new(Semaphore::new(5));
147     let mut join_handles = Vec::new();
148     for _ in 0..1000 {
149         let sem_clone = sem.clone();
150         join_handles.push(tokio::spawn(async move {
151             let _p = sem_clone.acquire_owned().await;
152         }));
153     }
154     for j in join_handles {
155         j.await.unwrap();
156     }
157     // there should be exactly 5 semaphores available now
158     let _p1 = sem.clone().try_acquire_owned().unwrap();
159     let _p2 = sem.clone().try_acquire_owned().unwrap();
160     let _p3 = sem.clone().try_acquire_owned().unwrap();
161     let _p4 = sem.clone().try_acquire_owned().unwrap();
162     let _p5 = sem.clone().try_acquire_owned().unwrap();
163     assert!(sem.try_acquire_owned().is_err());
164 }
165