• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(feature = "time")]
15 
16 use std::future::Future;
17 use std::pin::Pin;
18 use std::task::{Context, Poll};
19 use std::time::Duration;
20 
21 use ylong_runtime::error::ErrorKind;
22 use ylong_runtime::time::sleep;
23 
24 /// SDV test cases for canceling a task.
25 ///
26 /// # Brief
27 /// 1. Configure the RuntimeBuilder and start the runtime
28 /// 2. Spawn a task that takes 100 seconds
29 /// 3. Cancel the task after the task returns pending
30 /// 4. Await on the canceled task
31 /// 5. Check return value
32 #[test]
sdv_task_cancel_simple()33 fn sdv_task_cancel_simple() {
34     let handle = ylong_runtime::spawn(async move {
35         let task = ylong_runtime::spawn(async move {
36             sleep(Duration::from_secs(100)).await;
37         });
38         sleep(Duration::from_millis(100)).await;
39         task.cancel();
40         let res = task.await.err().unwrap();
41         assert_eq!(res.kind(), ErrorKind::TaskCanceled);
42     });
43     ylong_runtime::block_on(handle).unwrap();
44 }
45 
46 /// SDV test cases for canceling a task after its finished
47 ///
48 /// # Brief
49 /// 1. Configure the RuntimeBuilder and start the runtime
50 /// 2. Spawn a task that returns 1 immediately
51 /// 3. Cancel the task after the task is finished
52 /// 4. Await on the canceled task
53 /// 5. Check return value
54 #[test]
sdv_task_cancel_failed()55 fn sdv_task_cancel_failed() {
56     let handle = ylong_runtime::spawn(async move {
57         let task = ylong_runtime::spawn(async move { 1 });
58         sleep(Duration::from_millis(100)).await;
59         task.cancel();
60         let res = task.await.unwrap();
61         assert_eq!(res, 1);
62     });
63     ylong_runtime::block_on(handle).unwrap();
64 }
65 
66 #[derive(Default)]
67 struct TestFuture {
68     flag: usize,
69 }
70 
71 impl Future for TestFuture {
72     type Output = u8;
73 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>74     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
75         let this = self.get_mut();
76         if this.flag < 1000000 {
77             this.flag += 1;
78             cx.waker().wake_by_ref();
79             Poll::Pending
80         } else {
81             Poll::Ready(1)
82         }
83     }
84 }
85 
86 /// SDV test cases for multi cancel.
87 ///
88 /// # Brief
89 /// 1. In a loop, create a long-time task and then cancel it.
90 /// 2. Check if the task has been canceled for each run
91 #[test]
sdv_task_cancel_multiple()92 fn sdv_task_cancel_multiple() {
93     for _ in 0..1000 {
94         ylong_runtime::block_on(async move {
95             let handle = ylong_runtime::spawn(async move {
96                 TestFuture::default().await;
97                 sleep(Duration::from_secs(1000000));
98                 1
99             });
100             handle.cancel();
101             let res = handle.await;
102             assert!(res.is_err());
103         })
104     }
105 }
106