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}