1 #![deny(warnings)]
2
3 extern crate futures;
4 extern crate tokio_mock_task;
5 extern crate tokio_sync;
6
7 use tokio_mock_task::*;
8 use tokio_sync::semaphore::{Permit, Semaphore};
9
10 macro_rules! assert_ready {
11 ($e:expr) => {{
12 match $e {
13 Ok(futures::Async::Ready(v)) => v,
14 Ok(_) => panic!("not ready"),
15 Err(e) => panic!("error = {:?}", e),
16 }
17 }};
18 }
19
20 macro_rules! assert_not_ready {
21 ($e:expr) => {{
22 match $e {
23 Ok(futures::Async::NotReady) => {}
24 Ok(futures::Async::Ready(v)) => panic!("ready; value = {:?}", v),
25 Err(e) => panic!("error = {:?}", e),
26 }
27 }};
28 }
29
30 #[test]
available_permits()31 fn available_permits() {
32 let s = Semaphore::new(100);
33 assert_eq!(s.available_permits(), 100);
34
35 // Polling for a permit succeeds immediately
36 let mut permit = Permit::new();
37 assert!(!permit.is_acquired());
38
39 assert_ready!(permit.poll_acquire(&s));
40 assert_eq!(s.available_permits(), 99);
41 assert!(permit.is_acquired());
42
43 // Polling again on the same waiter does not claim a new permit
44 assert_ready!(permit.poll_acquire(&s));
45 assert_eq!(s.available_permits(), 99);
46 assert!(permit.is_acquired());
47 }
48
49 #[test]
unavailable_permits()50 fn unavailable_permits() {
51 let s = Semaphore::new(1);
52
53 let mut permit_1 = Permit::new();
54 let mut permit_2 = Permit::new();
55
56 // Acquire the first permit
57 assert_ready!(permit_1.poll_acquire(&s));
58 assert_eq!(s.available_permits(), 0);
59
60 let mut task = MockTask::new();
61
62 task.enter(|| {
63 // Try to acquire the second permit
64 assert_not_ready!(permit_2.poll_acquire(&s));
65 });
66
67 permit_1.release(&s);
68
69 assert_eq!(s.available_permits(), 0);
70 assert!(task.is_notified());
71 assert_ready!(permit_2.poll_acquire(&s));
72
73 permit_2.release(&s);
74 assert_eq!(s.available_permits(), 1);
75 }
76
77 #[test]
zero_permits()78 fn zero_permits() {
79 let s = Semaphore::new(0);
80 assert_eq!(s.available_permits(), 0);
81
82 let mut permit = Permit::new();
83 let mut task = MockTask::new();
84
85 // Try to acquire the permit
86 task.enter(|| {
87 assert_not_ready!(permit.poll_acquire(&s));
88 });
89
90 s.add_permits(1);
91
92 assert!(task.is_notified());
93 assert_ready!(permit.poll_acquire(&s));
94 }
95
96 #[test]
97 #[should_panic]
validates_max_permits()98 fn validates_max_permits() {
99 use std::usize;
100 Semaphore::new((usize::MAX >> 2) + 1);
101 }
102
103 #[test]
close_semaphore_prevents_acquire()104 fn close_semaphore_prevents_acquire() {
105 let s = Semaphore::new(1);
106 s.close();
107
108 assert_eq!(1, s.available_permits());
109
110 let mut permit = Permit::new();
111
112 assert!(permit.poll_acquire(&s).is_err());
113 assert_eq!(1, s.available_permits());
114 }
115
116 #[test]
close_semaphore_notifies_permit1()117 fn close_semaphore_notifies_permit1() {
118 let s = Semaphore::new(0);
119
120 let mut permit = Permit::new();
121 let mut task = MockTask::new();
122
123 task.enter(|| {
124 assert_not_ready!(permit.poll_acquire(&s));
125 });
126
127 s.close();
128
129 assert!(task.is_notified());
130 assert!(permit.poll_acquire(&s).is_err());
131 }
132
133 #[test]
close_semaphore_notifies_permit2()134 fn close_semaphore_notifies_permit2() {
135 let s = Semaphore::new(2);
136
137 let mut permit1 = Permit::new();
138 let mut permit2 = Permit::new();
139 let mut permit3 = Permit::new();
140 let mut permit4 = Permit::new();
141
142 // Acquire a couple of permits
143 assert_ready!(permit1.poll_acquire(&s));
144 assert_ready!(permit2.poll_acquire(&s));
145
146 let mut task1 = MockTask::new();
147 let mut task2 = MockTask::new();
148
149 task1.enter(|| {
150 assert_not_ready!(permit3.poll_acquire(&s));
151 });
152
153 task2.enter(|| {
154 assert_not_ready!(permit4.poll_acquire(&s));
155 });
156
157 s.close();
158
159 assert!(task1.is_notified());
160 assert!(task2.is_notified());
161
162 assert!(permit3.poll_acquire(&s).is_err());
163 assert!(permit4.poll_acquire(&s).is_err());
164
165 assert_eq!(0, s.available_permits());
166
167 permit1.release(&s);
168
169 assert_eq!(1, s.available_permits());
170
171 assert!(permit1.poll_acquire(&s).is_err());
172
173 permit2.release(&s);
174
175 assert_eq!(2, s.available_permits());
176 }
177