aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/tests/test.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-executor/tests/test.rs')
-rw-r--r--embassy-executor/tests/test.rs93
1 files changed, 83 insertions, 10 deletions
diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs
index 78c49c071..6baf3dc21 100644
--- a/embassy-executor/tests/test.rs
+++ b/embassy-executor/tests/test.rs
@@ -1,12 +1,13 @@
1#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] 1#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
2#![cfg_attr(feature = "nightly", feature(never_type))]
2 3
3use std::boxed::Box; 4use std::boxed::Box;
4use std::future::poll_fn; 5use std::future::{poll_fn, Future};
5use std::sync::{Arc, Mutex}; 6use std::sync::{Arc, Mutex};
6use std::task::Poll; 7use std::task::Poll;
7 8
8use embassy_executor::raw::Executor; 9use embassy_executor::raw::Executor;
9use embassy_executor::task; 10use embassy_executor::{task, Spawner};
10 11
11#[export_name = "__pender"] 12#[export_name = "__pender"]
12fn __pender(context: *mut ()) { 13fn __pender(context: *mut ()) {
@@ -58,8 +59,41 @@ fn executor_task() {
58 trace.push("poll task1") 59 trace.push("poll task1")
59 } 60 }
60 61
62 #[task]
63 async fn task2() -> ! {
64 panic!()
65 }
66
61 let (executor, trace) = setup(); 67 let (executor, trace) = setup();
62 executor.spawner().spawn(task1(trace.clone())).unwrap(); 68 executor.spawner().spawn(task1(trace.clone()).unwrap());
69
70 unsafe { executor.poll() };
71 unsafe { executor.poll() };
72
73 assert_eq!(
74 trace.get(),
75 &[
76 "pend", // spawning a task pends the executor
77 "poll task1", // poll only once.
78 ]
79 )
80}
81
82#[test]
83fn executor_task_rpit() {
84 #[task]
85 fn task1(trace: Trace) -> impl Future<Output = ()> {
86 async move { trace.push("poll task1") }
87 }
88
89 #[cfg(feature = "nightly")]
90 #[task]
91 fn task2() -> impl Future<Output = !> {
92 async { panic!() }
93 }
94
95 let (executor, trace) = setup();
96 executor.spawner().spawn(task1(trace.clone()).unwrap());
63 97
64 unsafe { executor.poll() }; 98 unsafe { executor.poll() };
65 unsafe { executor.poll() }; 99 unsafe { executor.poll() };
@@ -86,7 +120,7 @@ fn executor_task_self_wake() {
86 } 120 }
87 121
88 let (executor, trace) = setup(); 122 let (executor, trace) = setup();
89 executor.spawner().spawn(task1(trace.clone())).unwrap(); 123 executor.spawner().spawn(task1(trace.clone()).unwrap());
90 124
91 unsafe { executor.poll() }; 125 unsafe { executor.poll() };
92 unsafe { executor.poll() }; 126 unsafe { executor.poll() };
@@ -118,7 +152,7 @@ fn executor_task_self_wake_twice() {
118 } 152 }
119 153
120 let (executor, trace) = setup(); 154 let (executor, trace) = setup();
121 executor.spawner().spawn(task1(trace.clone())).unwrap(); 155 executor.spawner().spawn(task1(trace.clone()).unwrap());
122 156
123 unsafe { executor.poll() }; 157 unsafe { executor.poll() };
124 unsafe { executor.poll() }; 158 unsafe { executor.poll() };
@@ -154,7 +188,7 @@ fn waking_after_completion_does_not_poll() {
154 let waker = Box::leak(Box::new(AtomicWaker::new())); 188 let waker = Box::leak(Box::new(AtomicWaker::new()));
155 189
156 let (executor, trace) = setup(); 190 let (executor, trace) = setup();
157 executor.spawner().spawn(task1(trace.clone(), waker)).unwrap(); 191 executor.spawner().spawn(task1(trace.clone(), waker).unwrap());
158 192
159 unsafe { executor.poll() }; 193 unsafe { executor.poll() };
160 waker.wake(); 194 waker.wake();
@@ -166,7 +200,7 @@ fn waking_after_completion_does_not_poll() {
166 unsafe { executor.poll() }; // Clears running status 200 unsafe { executor.poll() }; // Clears running status
167 201
168 // Can respawn waken-but-dead task 202 // Can respawn waken-but-dead task
169 executor.spawner().spawn(task1(trace.clone(), waker)).unwrap(); 203 executor.spawner().spawn(task1(trace.clone(), waker).unwrap());
170 204
171 unsafe { executor.poll() }; 205 unsafe { executor.poll() };
172 206
@@ -216,7 +250,7 @@ fn waking_with_old_waker_after_respawn() {
216 let waker = Box::leak(Box::new(AtomicWaker::new())); 250 let waker = Box::leak(Box::new(AtomicWaker::new()));
217 251
218 let (executor, trace) = setup(); 252 let (executor, trace) = setup();
219 executor.spawner().spawn(task1(trace.clone(), waker)).unwrap(); 253 executor.spawner().spawn(task1(trace.clone(), waker).unwrap());
220 254
221 unsafe { executor.poll() }; 255 unsafe { executor.poll() };
222 unsafe { executor.poll() }; // progress to registering the waker 256 unsafe { executor.poll() }; // progress to registering the waker
@@ -239,8 +273,7 @@ fn waking_with_old_waker_after_respawn() {
239 let (other_executor, other_trace) = setup(); 273 let (other_executor, other_trace) = setup();
240 other_executor 274 other_executor
241 .spawner() 275 .spawner()
242 .spawn(task1(other_trace.clone(), waker)) 276 .spawn(task1(other_trace.clone(), waker).unwrap());
243 .unwrap();
244 277
245 unsafe { other_executor.poll() }; // just run to the yield_now 278 unsafe { other_executor.poll() }; // just run to the yield_now
246 waker.wake(); // trigger old waker registration 279 waker.wake(); // trigger old waker registration
@@ -283,3 +316,43 @@ fn executor_task_cfg_args() {
283 let (_, _, _) = (a, b, c); 316 let (_, _, _) = (a, b, c);
284 } 317 }
285} 318}
319
320#[test]
321fn recursive_task() {
322 #[embassy_executor::task(pool_size = 2)]
323 async fn task1() {
324 let spawner = unsafe { Spawner::for_current_executor().await };
325 spawner.spawn(task1().unwrap());
326 }
327}
328
329#[cfg(feature = "metadata-name")]
330#[test]
331fn task_metadata() {
332 #[task]
333 async fn task1(expected_name: Option<&'static str>) {
334 use embassy_executor::Metadata;
335 assert_eq!(Metadata::for_current_task().await.name(), expected_name);
336 }
337
338 // check no task name
339 let (executor, _) = setup();
340 executor.spawner().spawn(task1(None).unwrap());
341 unsafe { executor.poll() };
342
343 // check setting task name
344 let token = task1(Some("foo")).unwrap();
345 token.metadata().set_name("foo");
346 executor.spawner().spawn(token);
347 unsafe { executor.poll() };
348
349 let token = task1(Some("bar")).unwrap();
350 token.metadata().set_name("bar");
351 executor.spawner().spawn(token);
352 unsafe { executor.poll() };
353
354 // check name is cleared if the task pool slot is recycled.
355 let (executor, _) = setup();
356 executor.spawner().spawn(task1(None).unwrap());
357 unsafe { executor.poll() };
358}