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