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}