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