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}