1#![warn(rust_2018_idioms)]
2
3use tokio_test::{assert_pending, assert_ready, task};
4use tokio_util::task::TaskTracker;
5
6#[test]
7fn 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]
36fn 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]
55fn 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]
64fn 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]
74fn 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]
85fn 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]
97fn 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]
109fn 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]
123fn 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]
136fn 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]
164fn 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