xref: /aosp_15_r20/external/crosvm/cros_async/tests/executor.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2023 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use cros_async::sys::ExecutorKindSys;
6 use cros_async::Executor;
7 use cros_async::ExecutorKind;
8 
9 #[cfg(any(target_os = "android", target_os = "linux"))]
all_kinds() -> Vec<ExecutorKind>10 fn all_kinds() -> Vec<ExecutorKind> {
11     let mut kinds = vec![ExecutorKindSys::Fd.into()];
12     if cros_async::is_uring_stable() {
13         kinds.push(ExecutorKindSys::Uring.into());
14     }
15     kinds
16 }
17 #[cfg(windows)]
all_kinds() -> Vec<ExecutorKind>18 fn all_kinds() -> Vec<ExecutorKind> {
19     vec![ExecutorKindSys::Handle.into()]
20 }
21 
22 #[test]
cancel_pending_task()23 fn cancel_pending_task() {
24     for kind in all_kinds() {
25         let ex = Executor::with_executor_kind(kind).unwrap();
26         let task = ex.spawn(std::future::pending::<()>());
27         assert_eq!(ex.run_until(task.cancel()).unwrap(), None);
28     }
29 }
30 
31 // Testing a completed task without relying on implementation details is tricky. We create a future
32 // that signals a channel when it is polled so that we can delay the `task.cancel()` call until we
33 // know the task has been executed.
34 #[test]
cancel_ready_task()35 fn cancel_ready_task() {
36     for kind in all_kinds() {
37         let ex = Executor::with_executor_kind(kind).unwrap();
38         let (s, r) = futures::channel::oneshot::channel();
39         let mut s = Some(s);
40         let task = ex.spawn(futures::future::poll_fn(move |_| {
41             s.take().unwrap().send(()).unwrap();
42             std::task::Poll::Ready(5)
43         }));
44         assert_eq!(
45             ex.run_until(async {
46                 r.await.unwrap();
47                 task.cancel().await
48             })
49             .unwrap(),
50             Some(5)
51         );
52     }
53 }
54