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