Skip to main content

os_test_framework/
lib.rs

1//! # os-test-framework
2//!
3//! Test framework for embedded systems and OS kernels.
4//!
5//! `os-test-framework` requires `alloc`, so your kernel will need a `global-allocator`.
6//!
7//! ## Getting Started
8//!
9//! First, enable `custom_test_frameworks`, set `test_runner` as the test runner
10//! from `os-test-framework`, and `reexport_test_harness_main`.
11//!
12//! ```rust,ignore
13//! #![feature(custom_test_frameworks)]
14//! #![reexport_test_harness_main = "test_main"]
15//! #![test_runner(os_test_framework::run_tests)]
16//! ```
17//!
18//! Implement `Platform`. The framework writes output through
19//! `Platform::print` and finishes the run through `Platform::exit`:
20//!
21//! ```rust,ignore
22//! use core::fmt::Arguments;
23//! use os_test_framework::{ExitState, Platform};
24//!
25//! struct MyPlatform;
26//!
27//! impl Platform for MyPlatform {
28//!     fn print(&mut self, args: Arguments) {
29//!         let _ = args;
30//!         todo!()
31//!     }
32//!
33//!     fn exit(&self, state: ExitState) -> ! {
34//!         match state {
35//!             ExitState::Success => todo!(),
36//!             ExitState::Failed => todo!(),
37//!         }
38//!     }
39//! }
40//! ```
41//!
42//! Call `init_platform` with your `Platform`, and `test_main` from your kernel
43//! entry point:
44//!
45//! ```rust,ignore
46//! use os_test_framework::init_platform;
47//!
48//! fn kernel_entry() {
49//!     init_platform(MyPlatform);
50//!     test_main();
51//! }
52//! ```
53//!
54//! Forward panics from your OS to `os-test-framework`:
55//!
56//! ```rust,ignore
57//! os_test_framework::forward_panic!();
58//! ```
59//!
60//! ## Adding A Test
61//!
62//! You can declare tests like this:
63//!
64//! ```rust,ignore
65//! use os_test_framework::test;
66//!
67//! test! {
68//!     "Hello" {
69//!         assert!(true);
70//!     }
71//! }
72//! ```
73//!
74//! You can add multiple tests in the same file:
75//!
76//! ```rust,ignore
77//! use os_test_framework::test;
78//!
79//! test! {
80//!     "Hello" {
81//!         assert!(true);
82//!     }
83//! }
84//!
85//! test! {
86//!     "Hello2" {
87//!         assert!(true);
88//!     }
89//! }
90//! ```
91#![no_std]
92
93use owo_colors::OwoColorize;
94
95extern crate alloc;
96
97mod panic;
98mod platform;
99#[doc(hidden)]
100pub mod __private {
101    pub use crate::_run_test;
102    pub use crate::printing::_print;
103}
104
105pub use crate::{panic::*, platform::*};
106
107mod make_test;
108mod printing;
109
110pub fn run_tests(tests: &[&dyn Fn()]) -> ! {
111    println!("\nRunning {} tests", tests.len().bold());
112
113    for test in tests {
114        test()
115    }
116
117    platform().lock().exit(ExitState::Success);
118}
119
120#[doc(hidden)]
121pub fn _run_test(name: &str, func: impl FnOnce()) {
122    print!("{}", name);
123    func();
124    println!(" {}", "OK".green().bold());
125}