FluenTech / embedded-time

Time(ing) library (Instant/Duration/Clock/Timer/Period/Frequency) for bare-metal embedded systems
Apache License 2.0
87 stars 17 forks source link

[Proposal] std-powered Clock implementation for tests #112

Open ryan-summers opened 2 years ago

ryan-summers commented 2 years ago

Many crates that want an embedded_time::Clock may also want to have integration/unit tests that run on host. Is it possible to expose a std-powered embedded_time::Clock that can be easily used for unit/integration testing for dependent crates?

I'm deriving this idea from the std-embedded-nal, which provides an embedded_nal network stack implementation for std platforms.

I implemented an example of this in an MQTT integration test available at https://github.com/quartiq/minimq/blob/c2b0c41c18288e55dbc65831fdd43fb7419dea17/tests/integration_test.rs#L8-L32

Would such an implementation be desired for embedded-time? Are there any potential limitations of this approach?

An alternative is to take the approach of std-embedded-nal, where the std-powered implementation is distributed as a separate crate.

PTaylor-us commented 2 years ago

Thank you for opening the issue. Testing embedded software on the host system is near and dear to my heart. If I understand correctly, you're talking about a functional implementation of Clock for host systems that will actually return the current time. What would that time be, Unix time?

ryan-summers commented 2 years ago

If I understand correctly, you're talking about a functional implementation of Clock for host systems that will actually return the current time.

Correct - the intent is to have a usable clock. In the past, I've had the desire to "fast forward" a clock for unit testing purposes (e.g. if you have a 24 hour duration that you want to test, I assume you don't want the actual test to last 24 hours).

What would that time be, Unix time?

I created a crate that uses the internal std::time::Instant as the basis for timekeeping. Given the API of embedded-time, the underlying clock source is irrelevant, as it reports the time as "elapsed since clock instantiation" . However, I could also imagine use cases that allow some "global" timing source that can be accelerated as well (by the test software, necessary to bypass long waits in unit testing).

PTaylor-us commented 2 years ago

What I've done in the past to have a clock is simply use a mock and manually change the underlying clock count, but that can certainly make things pretty complicated when you have to spawn a new thread to change the clock count in the background while the code-under-test is waiting on it.

How would you "fast forward" if you are tied to a real clock?

If you have the time, I'd love to see an example of what tests might look like with this implemented.

sakian commented 2 years ago

@PTaylor-us, do you have an example of how you create a mock clock?

ryan-summers commented 2 years ago

As a follow up, I published a separate crate as std-embedded-time - I would be open to PRs to allow fast-forwarding time etc. or would be happy to incroporate it directly here as well