Skip to main content

bare_test/
lib.rs

1#![cfg(target_os = "none")]
2#![no_std]
3
4extern crate alloc;
5extern crate sparreal_rt;
6
7use core::{
8    ptr::slice_from_raw_parts,
9    sync::atomic::{AtomicBool, Ordering},
10    time::Duration,
11};
12
13use alloc::{format, string::String, sync::Arc};
14
15pub use bare_test_macros::tests;
16pub use sparreal_rt::*;
17
18mod test_case;
19
20#[sparreal_rt::entry]
21fn main() -> ! {
22    println!("begin test");
23
24    for test in test_case_list() {
25        println!(
26            "Run test: {}{}",
27            test.name,
28            if test.timeout_ms > 0 {
29                format!(" (timeout: {} ms)", test.timeout_ms)
30            } else {
31                String::new()
32            }
33        );
34        let finished = Arc::new(AtomicBool::new(false));
35        let f2 = finished.clone();
36        if test.timeout_ms > 0 {
37            sparreal_rt::os::time::one_shot_after(
38                Duration::from_millis(test.timeout_ms),
39                move || {
40                    if !f2.load(Ordering::SeqCst) {
41                        panic!("test {} timeout", test.name);
42                    }
43                },
44            )
45            .unwrap();
46        }
47
48        (test.test_fn)();
49        finished.store(true, Ordering::SeqCst);
50
51        println!("test {} passed", test.name);
52    }
53
54    println!("All tests passed");
55}
56
57#[repr(C)]
58#[derive(Clone)]
59pub struct TestCase {
60    pub name: &'static str,
61    pub timeout_ms: u64,
62    pub test_fn: fn(),
63}
64
65fn test_case_list() -> test_case::Iter<'static> {
66    unsafe extern "C" {
67        fn _stest_case();
68        fn _etest_case();
69    }
70
71    let data = _stest_case as *const () as usize as *const u8;
72    let len = _etest_case as *const () as usize - _stest_case as *const () as usize;
73
74    let list = test_case::ListRef::from_raw(unsafe { &*slice_from_raw_parts(data, len) });
75
76    list.iter()
77}