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