1#![cfg(feature = "sync")]
2
3#[cfg(all(target_family = "wasm", not(target_os = "wasi")))]
4use wasm_bindgen_test::wasm_bindgen_test as test;
5
6use std::sync::Arc;
7use tokio::sync::Semaphore;
8
9#[test]
10fn 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]
23fn 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")]
40async 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")]
53async 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")]
69async 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]
80fn 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]
93fn 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]
109fn 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#[tokio::test]
118#[cfg(feature = "full")]
119async fn stress_test() {
120 let sem = Arc::new(Semaphore::new(5));
121 let mut join_handles = Vec::new();
122 for _ in 0..1000 {
123 let sem_clone = sem.clone();
124 join_handles.push(tokio::spawn(async move {
125 let _p = sem_clone.acquire_owned().await;
126 }));
127 }
128 for j in join_handles {
129 j.await.unwrap();
130 }
131 // there should be exactly 5 semaphores available now
132 let _p1 = sem.clone().try_acquire_owned().unwrap();
133 let _p2 = sem.clone().try_acquire_owned().unwrap();
134 let _p3 = sem.clone().try_acquire_owned().unwrap();
135 let _p4 = sem.clone().try_acquire_owned().unwrap();
136 let _p5 = sem.clone().try_acquire_owned().unwrap();
137 assert!(sem.try_acquire_owned().is_err());
138}
139