1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 #![cfg(all(feature = "time", feature = "sync"))]
15
16 use std::time::Duration;
17
18 use ylong_runtime::sync::error::{RecvError, RecvTimeoutError, TryRecvError, TrySendError};
19 use ylong_runtime::sync::mpsc::{bounded_channel, unbounded_channel};
20
21 /// SDV test cases for `UnboundedSender`.
22 ///
23 /// # Brief
24 /// 1. Create a unbounded mpsc channel.
25 /// 2. Send two values to the receiver then drop.
26 /// 3. Receive two values successfully and then receive error.
27 #[test]
sdv_unbounded_send_recv_test()28 fn sdv_unbounded_send_recv_test() {
29 let (tx, mut rx) = unbounded_channel();
30 let handle = ylong_runtime::spawn(async move {
31 assert_eq!(rx.recv().await, Ok(1));
32 assert_eq!(rx.recv().await, Ok(2));
33 assert_eq!(rx.recv().await, Err(RecvError));
34 });
35 assert!(tx.send(1).is_ok());
36 assert!(tx.send(2).is_ok());
37 drop(tx);
38 let _ = ylong_runtime::block_on(handle);
39 }
40
41 /// SDV test cases for `UnboundedSender`.
42 ///
43 /// # Brief
44 /// 1. Create a unbounded mpsc channel.
45 /// 2. Send two values to the receiver then drop.
46 /// 3. Receive two values successfully.
47 #[test]
sdv_unbounded_send_recv_drop_test()48 fn sdv_unbounded_send_recv_drop_test() {
49 let (tx, mut rx) = unbounded_channel();
50 let handle = ylong_runtime::spawn(async move {
51 assert_eq!(rx.recv().await, Ok(1));
52 assert_eq!(rx.recv().await, Ok(2));
53 });
54 assert!(tx.send(1).is_ok());
55 assert!(tx.send(2).is_ok());
56 drop(tx);
57 let _ = ylong_runtime::block_on(handle);
58 }
59
60 /// SDV test cases for `UnboundedSender`.
61 ///
62 /// # Brief
63 /// 1. Create a unbounded mpsc channel.
64 /// 2. Try receiving before and after sender sends a value.
65 /// 3. Try receiving after sender has been dropped.
66 #[test]
sdv_unbounded_send_try_recv_test()67 fn sdv_unbounded_send_try_recv_test() {
68 let (tx, mut rx) = unbounded_channel();
69 assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
70 assert!(tx.send(1).is_ok());
71 assert_eq!(rx.try_recv(), Ok(1));
72 drop(tx);
73 assert_eq!(rx.try_recv(), Err(TryRecvError::Closed));
74 }
75
76 /// SDV test cases for `UnboundedSender`.
77 ///
78 /// # Brief
79 /// 1. Create a unbounded mpsc channel.
80 /// 2. Send a value to the receiver.
81 /// 3. Receive the value in the limited time twice.
82 #[test]
sdv_unbounded_send_recv_timeout_test()83 fn sdv_unbounded_send_recv_timeout_test() {
84 let (tx, mut rx) = unbounded_channel();
85 let handle = ylong_runtime::spawn(async move {
86 assert!(tx.send(1).is_ok());
87 assert_eq!(rx.recv_timeout(Duration::from_millis(10)).await, Ok(1));
88 assert_eq!(
89 rx.recv_timeout(Duration::from_millis(10)).await,
90 Err(RecvTimeoutError::Timeout)
91 );
92 });
93 let _ = ylong_runtime::block_on(handle);
94 }
95
96 /// SDV test cases for `BoundedSender`.
97 ///
98 /// # Brief
99 /// 1. Create a bounded mpsc channel with capacity.
100 /// 2. Send two value to the receiver.
101 /// 3. Receive two values successfully and then receive error.
102 #[test]
sdv_bounded_send_recv_test()103 fn sdv_bounded_send_recv_test() {
104 let (tx, mut rx) = bounded_channel::<i32>(1);
105 let handle = ylong_runtime::spawn(async move {
106 assert_eq!(rx.recv().await, Ok(1));
107 assert_eq!(rx.recv().await, Ok(2));
108 assert_eq!(rx.recv().await, Err(RecvError));
109 });
110
111 ylong_runtime::spawn(async move {
112 assert!(tx.send(1).await.is_ok());
113 assert!(tx.send(2).await.is_ok());
114 });
115 let _ = ylong_runtime::block_on(handle);
116 }
117
118 /// SDV test cases for `BoundedSender`.
119 ///
120 /// # Brief
121 /// 1. Create a bounded mpsc channel with capacity.
122 /// 2. Send two value to the receiver.
123 /// 3. Receive two values successfully.
124 #[test]
sdv_bounded_send_recv_drop_test()125 fn sdv_bounded_send_recv_drop_test() {
126 let (tx, mut rx) = bounded_channel::<i32>(3);
127 let handle = ylong_runtime::spawn(async move {
128 assert_eq!(rx.recv().await, Ok(1));
129 assert_eq!(rx.recv().await, Ok(2));
130 });
131
132 ylong_runtime::spawn(async move {
133 assert!(tx.send(1).await.is_ok());
134 assert!(tx.send(2).await.is_ok());
135 });
136 let _ = ylong_runtime::block_on(handle);
137 }
138
139 /// SDV test cases for `BoundedSender`.
140 ///
141 /// # Brief
142 /// 1. Create a bounded mpsc channel with capacity.
143 /// 2. Try receiving and fails.
144 /// 3. Try sending two values and one succeeds and one fails.
145 /// 4. Try receiving and succeeds.
146 /// 5. Drop the sender and then receiver fails to receive.
147 #[test]
sdv_bounded_try_send_try_recv_test()148 fn sdv_bounded_try_send_try_recv_test() {
149 let (tx, mut rx) = bounded_channel::<i32>(1);
150 assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
151 assert!(tx.try_send(1).is_ok());
152 assert_eq!(tx.try_send(2), Err(TrySendError::Full(2)));
153 assert_eq!(rx.try_recv(), Ok(1));
154 drop(tx);
155 assert_eq!(rx.try_recv(), Err(TryRecvError::Closed));
156 }
157
158 /// SDV test cases for `BoundedSender`.
159 ///
160 /// # Brief
161 /// 1. Create a bounded mpsc channel with capacity.
162 /// 2. Send two values to the receiver in the limited time and one succeeds and
163 /// one fails.
164 /// 3. Receive two values from the sender in the limited time and one succeeds
165 /// and one fails.
166 #[test]
sdv_bounded_send_timeout_recv_timeout_test()167 fn sdv_bounded_send_timeout_recv_timeout_test() {
168 let (tx, mut rx) = bounded_channel(1);
169 let handle = ylong_runtime::spawn(async move {
170 assert!(tx.send_timeout(1, Duration::from_millis(10)).await.is_ok());
171 assert!(tx.send_timeout(2, Duration::from_millis(10)).await.is_err());
172 assert_eq!(rx.recv_timeout(Duration::from_millis(10)).await, Ok(1));
173 assert_eq!(
174 rx.recv_timeout(Duration::from_millis(10)).await,
175 Err(RecvTimeoutError::Timeout)
176 );
177 });
178 let _ = ylong_runtime::block_on(handle);
179 }
180
181 /// SDV test cases for `BoundedSender` and `UnboundedSender`.
182 ///
183 /// # Brief
184 /// 1. Create a unbounded mpsc channel.
185 /// 2. Check the close state of unbounded channel before and after the receiver
186 /// is dropped.
187 /// 3. Create a bounded mpsc channel with capacity.
188 /// 4. Check the close state of bounded channel before and after the receiver is
189 /// dropped.
190 #[test]
sdv_mpsc_is_closed()191 fn sdv_mpsc_is_closed() {
192 let (tx, rx) = unbounded_channel::<i32>();
193 assert!(!tx.is_closed());
194 drop(rx);
195 assert!(tx.is_closed());
196 assert!(tx.send(1).is_err());
197
198 let (tx, rx) = bounded_channel::<i32>(1);
199 assert!(!tx.is_closed());
200 drop(rx);
201 assert!(tx.is_closed());
202 assert!(tx.try_send(1).is_err());
203 }
204
205 /// SDV test cases for `BoundedSender` and `UnboundedSender`.
206 ///
207 /// # Brief
208 /// 1. Create two unbounded mpsc channels.
209 /// 2. Check whether senders have the same source.
210 /// 3. Create two bounded mpsc channels with capacity.
211 /// 4. Check whether senders have the same source.
212 #[test]
sdv_mpsc_is_same()213 fn sdv_mpsc_is_same() {
214 let (tx, _) = unbounded_channel::<i32>();
215 let (tx2, _) = unbounded_channel::<i32>();
216
217 assert!(!tx.is_same(&tx2));
218 assert!(tx.is_same(&tx));
219
220 let (tx, _) = bounded_channel::<i32>(1);
221 let (tx2, _) = bounded_channel::<i32>(1);
222
223 assert!(!tx.is_same(&tx2));
224 assert!(tx.is_same(&tx));
225 }
226
227 /// SDV test cases for `BoundedSender` and `UnboundedSender`.
228 ///
229 /// # Brief
230 /// 1. Create two unbounded mpsc channels.
231 /// 2. Check the correctness of length of channel.
232 /// 3. Create two bounded mpsc channels with capacity.
233 /// 4. Check the correctness of length of channel.
234 #[test]
sdv_mpsc_len()235 fn sdv_mpsc_len() {
236 let (tx, mut rx) = unbounded_channel();
237 for i in 0..35 {
238 let _ = tx.send(i);
239 }
240 assert_eq!(rx.len(), 35);
241 for _ in 0..3 {
242 let _ = rx.try_recv();
243 }
244 assert_eq!(rx.len(), 32);
245 for _ in 0..33 {
246 let _ = rx.try_recv();
247 }
248 assert_eq!(rx.len(), 0);
249
250 let (tx, mut rx) = bounded_channel(10);
251 for i in 0..12 {
252 let _ = tx.try_send(i);
253 }
254 assert_eq!(rx.len(), 10);
255 for _ in 0..2 {
256 let _ = rx.try_recv();
257 }
258 assert_eq!(rx.len(), 8);
259 for _ in 0..9 {
260 let _ = rx.try_recv();
261 }
262 assert_eq!(rx.len(), 0);
263 }
264
265 /// SDV test cases for `BoundedSender` and `UnboundedSender`.
266 ///
267 /// # Brief
268 /// 1. Create a unbounded mpsc channel.
269 /// 2. Send and receive for many times.
270 /// 3. Create a bounded mpsc channel with capacity.
271 /// 4. Send and receive for many times.
272 #[test]
sdv_multi_send_recv_test()273 fn sdv_multi_send_recv_test() {
274 use ylong_runtime::task::JoinHandle;
275
276 let (tx, mut rx) = unbounded_channel();
277 let mut tasks: Vec<JoinHandle<()>> = Vec::new();
278 for i in 0..1000 {
279 let tx2 = tx.clone();
280 tasks.push(ylong_runtime::spawn(async move {
281 assert!(tx2.send(i).is_ok());
282 }));
283 }
284
285 let handle = ylong_runtime::spawn(async move {
286 for _ in 0..1000 {
287 assert!(rx.recv().await.is_ok());
288 }
289 assert!(rx.try_recv().is_err());
290 });
291 for t in tasks {
292 let _ = ylong_runtime::block_on(t);
293 }
294 let _ = ylong_runtime::block_on(handle);
295
296 let (tx, mut rx) = bounded_channel(10);
297 let mut tasks: Vec<JoinHandle<()>> = Vec::new();
298 for i in 0..1000 {
299 let tx2 = tx.clone();
300 tasks.push(ylong_runtime::spawn(async move {
301 assert_eq!(tx2.send(i).await, Ok(()));
302 }));
303 }
304
305 let handle = ylong_runtime::spawn(async move {
306 for _ in 0..1000 {
307 assert!(rx.recv().await.is_ok());
308 }
309 assert!(rx.try_recv().is_err());
310 });
311 for t in tasks {
312 let _ = ylong_runtime::block_on(t);
313 }
314 let _ = ylong_runtime::block_on(handle);
315 }
316