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] |
10 | fn no_permits() { |
11 | // this should not panic |
12 | Semaphore::new(0); |
13 | } |
14 | |
15 | #[test] |
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" )] |
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" )] |
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] |
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 | #[test] |
67 | fn merge() { |
68 | let sem = Arc::new(Semaphore::new(3)); |
69 | { |
70 | let mut p1 = sem.try_acquire().unwrap(); |
71 | assert_eq!(sem.available_permits(), 2); |
72 | let p2 = sem.try_acquire_many(2).unwrap(); |
73 | assert_eq!(sem.available_permits(), 0); |
74 | p1.merge(p2); |
75 | assert_eq!(sem.available_permits(), 0); |
76 | } |
77 | assert_eq!(sem.available_permits(), 3); |
78 | } |
79 | |
80 | #[test] |
81 | #[cfg (not(target_family = "wasm" ))] // No stack unwinding on wasm targets |
82 | #[should_panic ] |
83 | fn merge_unrelated_permits() { |
84 | let sem1 = Arc::new(Semaphore::new(3)); |
85 | let sem2 = Arc::new(Semaphore::new(3)); |
86 | let mut p1 = sem1.try_acquire().unwrap(); |
87 | let p2 = sem2.try_acquire().unwrap(); |
88 | p1.merge(p2); |
89 | } |
90 | |
91 | #[tokio::test ] |
92 | #[cfg (feature = "full" )] |
93 | async fn stress_test() { |
94 | let sem = Arc::new(Semaphore::new(5)); |
95 | let mut join_handles = Vec::new(); |
96 | for _ in 0..1000 { |
97 | let sem_clone = sem.clone(); |
98 | join_handles.push(tokio::spawn(async move { |
99 | let _p = sem_clone.acquire().await; |
100 | })); |
101 | } |
102 | for j in join_handles { |
103 | j.await.unwrap(); |
104 | } |
105 | // there should be exactly 5 semaphores available now |
106 | let _p1 = sem.try_acquire().unwrap(); |
107 | let _p2 = sem.try_acquire().unwrap(); |
108 | let _p3 = sem.try_acquire().unwrap(); |
109 | let _p4 = sem.try_acquire().unwrap(); |
110 | let _p5 = sem.try_acquire().unwrap(); |
111 | assert!(sem.try_acquire().is_err()); |
112 | } |
113 | |
114 | #[test] |
115 | fn add_max_amount_permits() { |
116 | let s = tokio::sync::Semaphore::new(0); |
117 | s.add_permits(tokio::sync::Semaphore::MAX_PERMITS); |
118 | assert_eq!(s.available_permits(), tokio::sync::Semaphore::MAX_PERMITS); |
119 | } |
120 | |
121 | #[cfg (not(target_family = "wasm" ))] // wasm currently doesn't support unwinding |
122 | #[test] |
123 | #[should_panic ] |
124 | fn add_more_than_max_amount_permits1() { |
125 | let s = tokio::sync::Semaphore::new(1); |
126 | s.add_permits(tokio::sync::Semaphore::MAX_PERMITS); |
127 | } |
128 | |
129 | #[cfg (not(target_family = "wasm" ))] // wasm currently doesn't support unwinding |
130 | #[test] |
131 | #[should_panic ] |
132 | fn add_more_than_max_amount_permits2() { |
133 | let s = Semaphore::new(Semaphore::MAX_PERMITS - 1); |
134 | s.add_permits(1); |
135 | s.add_permits(1); |
136 | } |
137 | |
138 | #[cfg (not(target_family = "wasm" ))] // wasm currently doesn't support unwinding |
139 | #[test] |
140 | #[should_panic ] |
141 | fn panic_when_exceeds_maxpermits() { |
142 | let _ = Semaphore::new(Semaphore::MAX_PERMITS + 1); |
143 | } |
144 | |
145 | #[test] |
146 | fn no_panic_at_maxpermits() { |
147 | let _ = Semaphore::new(Semaphore::MAX_PERMITS); |
148 | let s = Semaphore::new(Semaphore::MAX_PERMITS - 1); |
149 | s.add_permits(1); |
150 | } |
151 | |