aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Price <[email protected]>2024-01-09 14:07:06 +0000
committerChris Price <[email protected]>2024-01-09 15:17:25 +0000
commit9bf655ccd770a56e33c8de63382407538da094e6 (patch)
tree42ddd5037829a1a9ac02bd5f1414dd80944f51ec
parente4e2b314025e82388c10d7847e873de767e6194f (diff)
Use MockDriver in queue_generic tests
-rw-r--r--embassy-time/src/driver_mock.rs18
-rw-r--r--embassy-time/src/queue_generic.rs100
2 files changed, 25 insertions, 93 deletions
diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs
index 5828dde41..bbb012f62 100644
--- a/embassy-time/src/driver_mock.rs
+++ b/embassy-time/src/driver_mock.rs
@@ -164,10 +164,19 @@ unsafe impl Send for AlarmState {}
164 164
165#[cfg(test)] 165#[cfg(test)]
166mod tests { 166mod tests {
167 use serial_test::serial;
168
167 use super::*; 169 use super::*;
168 170
171 fn setup() {
172 DRIVER.reset();
173 }
174
169 #[test] 175 #[test]
176 #[serial]
170 fn test_advance() { 177 fn test_advance() {
178 setup();
179
171 let driver = MockDriver::get(); 180 let driver = MockDriver::get();
172 let reference = driver.now(); 181 let reference = driver.now();
173 driver.advance(Duration::from_secs(1)); 182 driver.advance(Duration::from_secs(1));
@@ -175,14 +184,20 @@ mod tests {
175 } 184 }
176 185
177 #[test] 186 #[test]
187 #[serial]
178 fn test_set_alarm_not_in_future() { 188 fn test_set_alarm_not_in_future() {
189 setup();
190
179 let driver = MockDriver::get(); 191 let driver = MockDriver::get();
180 let alarm = unsafe { AlarmHandle::new(0) }; 192 let alarm = unsafe { AlarmHandle::new(0) };
181 assert_eq!(false, driver.set_alarm(alarm, driver.now())); 193 assert_eq!(false, driver.set_alarm(alarm, driver.now()));
182 } 194 }
183 195
184 #[test] 196 #[test]
197 #[serial]
185 fn test_alarm() { 198 fn test_alarm() {
199 setup();
200
186 let driver = MockDriver::get(); 201 let driver = MockDriver::get();
187 let alarm = unsafe { driver.allocate_alarm() }.expect("No alarms available"); 202 let alarm = unsafe { driver.allocate_alarm() }.expect("No alarms available");
188 static mut CALLBACK_CALLED: bool = false; 203 static mut CALLBACK_CALLED: bool = false;
@@ -195,7 +210,10 @@ mod tests {
195 } 210 }
196 211
197 #[test] 212 #[test]
213 #[serial]
198 fn test_allocate_alarm() { 214 fn test_allocate_alarm() {
215 setup();
216
199 let driver = MockDriver::get(); 217 let driver = MockDriver::get();
200 assert!(unsafe { driver.allocate_alarm() }.is_some()); 218 assert!(unsafe { driver.allocate_alarm() }.is_some());
201 assert!(unsafe { driver.allocate_alarm() }.is_none()); 219 assert!(unsafe { driver.allocate_alarm() }.is_none());
diff --git a/embassy-time/src/queue_generic.rs b/embassy-time/src/queue_generic.rs
index 77947ab29..89fedf54c 100644
--- a/embassy-time/src/queue_generic.rs
+++ b/embassy-time/src/queue_generic.rs
@@ -175,6 +175,7 @@ impl TimerQueue for Queue {
175crate::timer_queue_impl!(static QUEUE: Queue = Queue::new()); 175crate::timer_queue_impl!(static QUEUE: Queue = Queue::new());
176 176
177#[cfg(test)] 177#[cfg(test)]
178#[cfg(feature = "mock-driver")]
178mod tests { 179mod tests {
179 use core::cell::Cell; 180 use core::cell::Cell;
180 use core::task::{RawWaker, RawWakerVTable, Waker}; 181 use core::task::{RawWaker, RawWakerVTable, Waker};
@@ -184,94 +185,9 @@ mod tests {
184 use serial_test::serial; 185 use serial_test::serial;
185 186
186 use crate::driver::{AlarmHandle, Driver}; 187 use crate::driver::{AlarmHandle, Driver};
188 use crate::driver_mock::MockDriver;
187 use crate::queue_generic::QUEUE; 189 use crate::queue_generic::QUEUE;
188 use crate::Instant; 190 use crate::{Instant, Duration};
189
190 struct InnerTestDriver {
191 now: u64,
192 alarm: u64,
193 callback: fn(*mut ()),
194 ctx: *mut (),
195 }
196
197 impl InnerTestDriver {
198 const fn new() -> Self {
199 Self {
200 now: 0,
201 alarm: u64::MAX,
202 callback: Self::noop,
203 ctx: core::ptr::null_mut(),
204 }
205 }
206
207 fn noop(_ctx: *mut ()) {}
208 }
209
210 unsafe impl Send for InnerTestDriver {}
211
212 struct TestDriver(Mutex<InnerTestDriver>);
213
214 impl TestDriver {
215 const fn new() -> Self {
216 Self(Mutex::new(InnerTestDriver::new()))
217 }
218
219 fn reset(&self) {
220 *self.0.lock().unwrap() = InnerTestDriver::new();
221 }
222
223 fn set_now(&self, now: u64) {
224 let notify = {
225 let mut inner = self.0.lock().unwrap();
226
227 if inner.now < now {
228 inner.now = now;
229
230 if inner.alarm <= now {
231 inner.alarm = u64::MAX;
232
233 Some((inner.callback, inner.ctx))
234 } else {
235 None
236 }
237 } else {
238 panic!("Going back in time?");
239 }
240 };
241
242 if let Some((callback, ctx)) = notify {
243 (callback)(ctx);
244 }
245 }
246 }
247
248 impl Driver for TestDriver {
249 fn now(&self) -> u64 {
250 self.0.lock().unwrap().now
251 }
252
253 unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
254 Some(AlarmHandle::new(0))
255 }
256
257 fn set_alarm_callback(&self, _alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
258 let mut inner = self.0.lock().unwrap();
259
260 inner.callback = callback;
261 inner.ctx = ctx;
262 }
263
264 fn set_alarm(&self, _alarm: AlarmHandle, timestamp: u64) -> bool {
265 let mut inner = self.0.lock().unwrap();
266
267 if timestamp <= inner.now {
268 false
269 } else {
270 inner.alarm = timestamp;
271 true
272 }
273 }
274 }
275 191
276 struct TestWaker { 192 struct TestWaker {
277 pub awoken: Rc<Cell<bool>>, 193 pub awoken: Rc<Cell<bool>>,
@@ -312,10 +228,8 @@ mod tests {
312 } 228 }
313 } 229 }
314 230
315 crate::time_driver_impl!(static DRIVER: TestDriver = TestDriver::new());
316
317 fn setup() { 231 fn setup() {
318 DRIVER.reset(); 232 MockDriver::get().reset();
319 critical_section::with(|cs| *QUEUE.inner.borrow_ref_mut(cs) = None); 233 critical_section::with(|cs| *QUEUE.inner.borrow_ref_mut(cs) = None);
320 } 234 }
321 235
@@ -382,13 +296,13 @@ mod tests {
382 296
383 assert!(!waker.awoken.get()); 297 assert!(!waker.awoken.get());
384 298
385 DRIVER.set_now(Instant::from_secs(99).as_ticks()); 299 MockDriver::get().advance(Duration::from_secs(99));
386 300
387 assert!(!waker.awoken.get()); 301 assert!(!waker.awoken.get());
388 302
389 assert_eq!(queue_len(), 1); 303 assert_eq!(queue_len(), 1);
390 304
391 DRIVER.set_now(Instant::from_secs(100).as_ticks()); 305 MockDriver::get().advance(Duration::from_secs(1));
392 306
393 assert!(waker.awoken.get()); 307 assert!(waker.awoken.get());
394 308
@@ -404,7 +318,7 @@ mod tests {
404 318
405 QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker); 319 QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker);
406 320
407 DRIVER.set_now(Instant::from_secs(50).as_ticks()); 321 MockDriver::get().advance(Duration::from_secs(50));
408 322
409 let waker2 = TestWaker::new(); 323 let waker2 = TestWaker::new();
410 324