aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-10-31 01:10:19 +0000
committerGitHub <[email protected]>2023-10-31 01:10:19 +0000
commit78739d4aa9e4403707f51cc1a01db143139e7b68 (patch)
tree5da6e86d20a05845056fa4efe9ac8bac8ba490af
parente07e7906130de73b2b841bd9ec46694661ff8558 (diff)
parent573734008a8a0659e6cfe832db382b9206e3f4f1 (diff)
Merge pull request #2120 from andresovela/time-mock-driver
time: add `MockDriver` for testing purposes
-rw-r--r--embassy-time/Cargo.toml3
-rw-r--r--embassy-time/src/driver_mock.rs68
-rw-r--r--embassy-time/src/lib.rs6
3 files changed, 77 insertions, 0 deletions
diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml
index 62404863d..8b5d31ee1 100644
--- a/embassy-time/Cargo.toml
+++ b/embassy-time/Cargo.toml
@@ -59,6 +59,9 @@ generic-queue-32 = ["generic-queue"]
59generic-queue-64 = ["generic-queue"] 59generic-queue-64 = ["generic-queue"]
60generic-queue-128 = ["generic-queue"] 60generic-queue-128 = ["generic-queue"]
61 61
62# Create a `MockDriver` that can be manually advanced for testing purposes.
63mock-driver = ["tick-hz-1_000_000"]
64
62# Set the `embassy_time` tick rate. 65# Set the `embassy_time` tick rate.
63# 66#
64# At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used. 67# At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used.
diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs
new file mode 100644
index 000000000..becb6bfdd
--- /dev/null
+++ b/embassy-time/src/driver_mock.rs
@@ -0,0 +1,68 @@
1use core::cell::Cell;
2
3use critical_section::Mutex as CsMutex;
4
5use crate::driver::{AlarmHandle, Driver};
6use crate::{Duration, Instant};
7
8/// A mock driver that can be manually advanced.
9/// This is useful for testing code that works with [`Instant`] and [`Duration`].
10///
11/// This driver cannot currently be used to test runtime functionality, such as
12/// timers, delays, etc.
13///
14/// # Example
15///
16/// ```ignore
17/// fn has_a_second_passed(reference: Instant) -> bool {
18/// Instant::now().duration_since(reference) >= Duration::from_secs(1)
19/// }
20///
21/// fn test_second_passed() {
22/// let driver = embassy_time::MockDriver::get();
23/// let reference = Instant::now();
24/// assert_eq!(false, has_a_second_passed(reference));
25/// driver.advance(Duration::from_secs(1));
26/// assert_eq!(true, has_a_second_passed(reference));
27/// }
28/// ```
29pub struct MockDriver {
30 now: CsMutex<Cell<Instant>>,
31}
32
33crate::time_driver_impl!(static DRIVER: MockDriver = MockDriver {
34 now: CsMutex::new(Cell::new(Instant::from_ticks(0))),
35});
36
37impl MockDriver {
38 /// Gets a reference to the global mock driver.
39 pub fn get() -> &'static MockDriver {
40 &DRIVER
41 }
42
43 /// Advances the time by the specified [`Duration`].
44 pub fn advance(&self, duration: Duration) {
45 critical_section::with(|cs| {
46 let now = self.now.borrow(cs).get().as_ticks();
47 self.now.borrow(cs).set(Instant::from_ticks(now + duration.as_ticks()));
48 });
49 }
50}
51
52impl Driver for MockDriver {
53 fn now(&self) -> u64 {
54 critical_section::with(|cs| self.now.borrow(cs).get().as_micros() as u64)
55 }
56
57 unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
58 unimplemented!("MockDriver does not support runtime features that require an executor");
59 }
60
61 fn set_alarm_callback(&self, _alarm: AlarmHandle, _callback: fn(*mut ()), _ctx: *mut ()) {
62 unimplemented!("MockDriver does not support runtime features that require an executor");
63 }
64
65 fn set_alarm(&self, _alarm: AlarmHandle, _timestamp: u64) -> bool {
66 unimplemented!("MockDriver does not support runtime features that require an executor");
67 }
68}
diff --git a/embassy-time/src/lib.rs b/embassy-time/src/lib.rs
index 8f57eabcb..45c1e882b 100644
--- a/embassy-time/src/lib.rs
+++ b/embassy-time/src/lib.rs
@@ -15,6 +15,12 @@ pub mod queue;
15mod tick; 15mod tick;
16mod timer; 16mod timer;
17 17
18#[cfg(feature = "mock-driver")]
19mod driver_mock;
20
21#[cfg(feature = "mock-driver")]
22pub use driver_mock::MockDriver;
23
18#[cfg(feature = "std")] 24#[cfg(feature = "std")]
19mod driver_std; 25mod driver_std;
20#[cfg(feature = "wasm")] 26#[cfg(feature = "wasm")]