capsules_core/test/capsule_test.rs
1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2024.
4
5//! Interface for running capsule tests.
6//!
7//! As Tock capsules are asynchronous, it is difficult for a test runner to
8//! determine when a test has finished. This interface provides a `done()`
9//! callback used by the test implementation to notify when the test has
10//! completed.
11//!
12//! A simple example of a test capsule using this interface:
13//!
14//! ```rust,ignore
15//! pub struct TestSensorX {
16//! client: OptionalCell<&'static dyn CapsuleTestClient>,
17//! }
18//!
19//! impl TestSensorX {
20//! pub fn new() -> Self {
21//! TestHmacSha256 {
22//! client: OptionalCell::empty(),
23//! }
24//! }
25//! }
26//!
27//! impl CapsuleTest for TestSensorX {
28//! fn set_client(&self, client: &'static dyn CapsuleTestClient) {
29//! self.client.set(client);
30//! }
31//! }
32//!
33//! impl AsyncClient for TestSensorX {
34//! fn operation_complete(&self) {
35//! // Test has finished at this point.
36//! self.client.map(|client| {
37//! client.done(Ok(()));
38//! });
39//! }
40//! }
41//! ```
42
43use kernel::ErrorCode;
44
45/// Errors for the result of a failed test.
46pub enum CapsuleTestError {
47 /// The test computed some result (e.g., a checksum or hash) and the result
48 /// is not correct (e.g., it doesn't match the intended value, say the
49 /// correct checksum or hash).
50 IncorrectResult,
51
52 /// An error occurred while running the test, and the resulting `ErrorCode`
53 /// is provided.
54 ErrorCode(ErrorCode),
55}
56
57/// Client for receiving test done events.
58pub trait CapsuleTestClient {
59 /// Called when the test is finished. If the test was successful, `result`
60 /// is `Ok(())`. If the test failed, `result` is `Err()` with a suitable
61 /// error.
62 fn done(&'static self, result: Result<(), CapsuleTestError>);
63}
64
65/// Identify a test as a capsule test. This is only used for setting the client
66/// for test complete callbacks.
67pub trait CapsuleTest {
68 /// Set the client for the done callback.
69 fn set_client(&self, client: &'static dyn CapsuleTestClient);
70}