1 #![warn(rust_2018_idioms)]
2 
3 use tokio_test::{assert_pending, assert_ready, task};
4 use tokio_util::task::TaskTracker;
5 
6 #[test]
open_close()7 fn open_close() {
8     let tracker = TaskTracker::new();
9     assert!(!tracker.is_closed());
10     assert!(tracker.is_empty());
11     assert_eq!(tracker.len(), 0);
12 
13     tracker.close();
14     assert!(tracker.is_closed());
15     assert!(tracker.is_empty());
16     assert_eq!(tracker.len(), 0);
17 
18     tracker.reopen();
19     assert!(!tracker.is_closed());
20     tracker.reopen();
21     assert!(!tracker.is_closed());
22 
23     assert!(tracker.is_empty());
24     assert_eq!(tracker.len(), 0);
25 
26     tracker.close();
27     assert!(tracker.is_closed());
28     tracker.close();
29     assert!(tracker.is_closed());
30 
31     assert!(tracker.is_empty());
32     assert_eq!(tracker.len(), 0);
33 }
34 
35 #[test]
token_len()36 fn token_len() {
37     let tracker = TaskTracker::new();
38 
39     let mut tokens = Vec::new();
40     for i in 0..10 {
41         assert_eq!(tracker.len(), i);
42         tokens.push(tracker.token());
43     }
44 
45     assert!(!tracker.is_empty());
46     assert_eq!(tracker.len(), 10);
47 
48     for (i, token) in tokens.into_iter().enumerate() {
49         drop(token);
50         assert_eq!(tracker.len(), 9 - i);
51     }
52 }
53 
54 #[test]
notify_immediately()55 fn notify_immediately() {
56     let tracker = TaskTracker::new();
57     tracker.close();
58 
59     let mut wait = task::spawn(tracker.wait());
60     assert_ready!(wait.poll());
61 }
62 
63 #[test]
notify_immediately_on_reopen()64 fn notify_immediately_on_reopen() {
65     let tracker = TaskTracker::new();
66     tracker.close();
67 
68     let mut wait = task::spawn(tracker.wait());
69     tracker.reopen();
70     assert_ready!(wait.poll());
71 }
72 
73 #[test]
notify_on_close()74 fn notify_on_close() {
75     let tracker = TaskTracker::new();
76 
77     let mut wait = task::spawn(tracker.wait());
78 
79     assert_pending!(wait.poll());
80     tracker.close();
81     assert_ready!(wait.poll());
82 }
83 
84 #[test]
notify_on_close_reopen()85 fn notify_on_close_reopen() {
86     let tracker = TaskTracker::new();
87 
88     let mut wait = task::spawn(tracker.wait());
89 
90     assert_pending!(wait.poll());
91     tracker.close();
92     tracker.reopen();
93     assert_ready!(wait.poll());
94 }
95 
96 #[test]
notify_on_last_task()97 fn notify_on_last_task() {
98     let tracker = TaskTracker::new();
99     tracker.close();
100     let token = tracker.token();
101 
102     let mut wait = task::spawn(tracker.wait());
103     assert_pending!(wait.poll());
104     drop(token);
105     assert_ready!(wait.poll());
106 }
107 
108 #[test]
notify_on_last_task_respawn()109 fn notify_on_last_task_respawn() {
110     let tracker = TaskTracker::new();
111     tracker.close();
112     let token = tracker.token();
113 
114     let mut wait = task::spawn(tracker.wait());
115     assert_pending!(wait.poll());
116     drop(token);
117     let token2 = tracker.token();
118     assert_ready!(wait.poll());
119     drop(token2);
120 }
121 
122 #[test]
no_notify_on_respawn_if_open()123 fn no_notify_on_respawn_if_open() {
124     let tracker = TaskTracker::new();
125     let token = tracker.token();
126 
127     let mut wait = task::spawn(tracker.wait());
128     assert_pending!(wait.poll());
129     drop(token);
130     let token2 = tracker.token();
131     assert_pending!(wait.poll());
132     drop(token2);
133 }
134 
135 #[test]
close_during_exit()136 fn close_during_exit() {
137     const ITERS: usize = 5;
138 
139     for close_spot in 0..=ITERS {
140         let tracker = TaskTracker::new();
141         let tokens: Vec<_> = (0..ITERS).map(|_| tracker.token()).collect();
142 
143         let mut wait = task::spawn(tracker.wait());
144 
145         for (i, token) in tokens.into_iter().enumerate() {
146             assert_pending!(wait.poll());
147             if i == close_spot {
148                 tracker.close();
149                 assert_pending!(wait.poll());
150             }
151             drop(token);
152         }
153 
154         if close_spot == ITERS {
155             assert_pending!(wait.poll());
156             tracker.close();
157         }
158 
159         assert_ready!(wait.poll());
160     }
161 }
162 
163 #[test]
notify_many()164 fn notify_many() {
165     let tracker = TaskTracker::new();
166 
167     let mut waits: Vec<_> = (0..10).map(|_| task::spawn(tracker.wait())).collect();
168 
169     for wait in &mut waits {
170         assert_pending!(wait.poll());
171     }
172 
173     tracker.close();
174 
175     for wait in &mut waits {
176         assert_ready!(wait.poll());
177     }
178 }
179