aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.github/ci/test.sh2
-rw-r--r--embassy-executor/Cargo.toml3
-rw-r--r--embassy-executor/tests/test.rs137
-rw-r--r--rust-toolchain.toml2
4 files changed, 143 insertions, 1 deletions
diff --git a/.github/ci/test.sh b/.github/ci/test.sh
index af0f21c2a..e48d6e65b 100755
--- a/.github/ci/test.sh
+++ b/.github/ci/test.sh
@@ -15,6 +15,8 @@ export CARGO_NET_GIT_FETCH_WITH_CLI=true
15hashtime restore /ci/cache/filetime.json || true 15hashtime restore /ci/cache/filetime.json || true
16hashtime save /ci/cache/filetime.json 16hashtime save /ci/cache/filetime.json
17 17
18MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml --features nightly
19
18cargo test --manifest-path ./embassy-sync/Cargo.toml 20cargo test --manifest-path ./embassy-sync/Cargo.toml
19cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml 21cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml
20cargo test --manifest-path ./embassy-hal-internal/Cargo.toml 22cargo test --manifest-path ./embassy-hal-internal/Cargo.toml
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml
index 54ea1a548..f0e85a2c8 100644
--- a/embassy-executor/Cargo.toml
+++ b/embassy-executor/Cargo.toml
@@ -68,3 +68,6 @@ cortex-m = { version = "0.7.6", optional = true }
68# arch-wasm dependencies 68# arch-wasm dependencies
69wasm-bindgen = { version = "0.2.82", optional = true } 69wasm-bindgen = { version = "0.2.82", optional = true }
70js-sys = { version = "0.3", optional = true } 70js-sys = { version = "0.3", optional = true }
71
72[dev-dependencies]
73critical-section = { version = "1.1", features = ["std"] }
diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs
new file mode 100644
index 000000000..0dbd391e8
--- /dev/null
+++ b/embassy-executor/tests/test.rs
@@ -0,0 +1,137 @@
1#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
2
3use std::boxed::Box;
4use std::future::poll_fn;
5use std::sync::{Arc, Mutex};
6use std::task::Poll;
7
8use embassy_executor::raw::Executor;
9use embassy_executor::task;
10
11#[export_name = "__pender"]
12fn __pender(context: *mut ()) {
13 unsafe {
14 let trace = &*(context as *const Trace);
15 trace.push("pend");
16 }
17}
18
19#[derive(Clone)]
20struct Trace {
21 trace: Arc<Mutex<Vec<&'static str>>>,
22}
23
24impl Trace {
25 fn new() -> Self {
26 Self {
27 trace: Arc::new(Mutex::new(Vec::new())),
28 }
29 }
30 fn push(&self, value: &'static str) {
31 self.trace.lock().unwrap().push(value)
32 }
33
34 fn get(&self) -> Vec<&'static str> {
35 self.trace.lock().unwrap().clone()
36 }
37}
38
39fn setup() -> (&'static Executor, Trace) {
40 let trace = Trace::new();
41 let context = Box::leak(Box::new(trace.clone())) as *mut _ as *mut ();
42 let executor = &*Box::leak(Box::new(Executor::new(context)));
43 (executor, trace)
44}
45
46#[test]
47fn executor_noop() {
48 let (executor, trace) = setup();
49 unsafe { executor.poll() };
50 assert!(trace.get().is_empty())
51}
52
53#[test]
54fn executor_task() {
55 #[task]
56 async fn task1(trace: Trace) {
57 trace.push("poll task1")
58 }
59
60 let (executor, trace) = setup();
61 executor.spawner().spawn(task1(trace.clone())).unwrap();
62
63 unsafe { executor.poll() };
64 unsafe { executor.poll() };
65
66 assert_eq!(
67 trace.get(),
68 &[
69 "pend", // spawning a task pends the executor
70 "poll task1", // poll only once.
71 ]
72 )
73}
74
75#[test]
76fn executor_task_self_wake() {
77 #[task]
78 async fn task1(trace: Trace) {
79 poll_fn(|cx| {
80 trace.push("poll task1");
81 cx.waker().wake_by_ref();
82 Poll::Pending
83 })
84 .await
85 }
86
87 let (executor, trace) = setup();
88 executor.spawner().spawn(task1(trace.clone())).unwrap();
89
90 unsafe { executor.poll() };
91 unsafe { executor.poll() };
92
93 assert_eq!(
94 trace.get(),
95 &[
96 "pend", // spawning a task pends the executor
97 "poll task1", //
98 "pend", // task self-wakes
99 "poll task1", //
100 "pend", // task self-wakes
101 ]
102 )
103}
104
105#[test]
106fn executor_task_self_wake_twice() {
107 #[task]
108 async fn task1(trace: Trace) {
109 poll_fn(|cx| {
110 trace.push("poll task1");
111 cx.waker().wake_by_ref();
112 trace.push("poll task1 wake 2");
113 cx.waker().wake_by_ref();
114 Poll::Pending
115 })
116 .await
117 }
118
119 let (executor, trace) = setup();
120 executor.spawner().spawn(task1(trace.clone())).unwrap();
121
122 unsafe { executor.poll() };
123 unsafe { executor.poll() };
124
125 assert_eq!(
126 trace.get(),
127 &[
128 "pend", // spawning a task pends the executor
129 "poll task1", //
130 "pend", // task self-wakes
131 "poll task1 wake 2", // task self-wakes again, shouldn't pend
132 "poll task1", //
133 "pend", // task self-wakes
134 "poll task1 wake 2", // task self-wakes again, shouldn't pend
135 ]
136 )
137}
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index 419c31085..11f53ee4a 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -2,7 +2,7 @@
2# https://rust-lang.github.io/rustup-components-history 2# https://rust-lang.github.io/rustup-components-history
3[toolchain] 3[toolchain]
4channel = "nightly-2023-11-01" 4channel = "nightly-2023-11-01"
5components = [ "rust-src", "rustfmt", "llvm-tools" ] 5components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ]
6targets = [ 6targets = [
7 "thumbv7em-none-eabi", 7 "thumbv7em-none-eabi",
8 "thumbv7m-none-eabi", 8 "thumbv7m-none-eabi",