1mod guard;
2pub mod macros;
3pub mod net_test;
4use crate::{
5 arch::intr::{are_interrupts_enabled, disable_interrupts, enable_interrupts},
6 earlyprintln,
7};
8
9#[cfg(test)]
11pub fn test_runner(tests: &[&dyn Fn()]) {
12 use crate::{arch::lib::sbi::shutdown, earlyprintln, test::macros::TEST_FAILED};
13 use core::sync::atomic::Ordering;
14 earlyprintln!("\n\x1b[33m--- Running {} tests ---\x1b[0m", tests.len());
15
16 TEST_FAILED.store(0, Ordering::SeqCst);
18
19 for test in tests {
21 test();
22 }
23
24 let failed = TEST_FAILED.load(Ordering::SeqCst);
25 earlyprintln!("\x1b[33m\n--- Test Summary ---\x1b[0m");
26 earlyprintln!(
27 "\x1b[33mTotal: {}\x1b[0m, \x1b[32mPassed: {}\x1b[0m, \x1b[91mFailed: {}\x1b[0m, \x1b[33mTests Finished\x1b[0m",
28 tests.len(),
29 tests.len() - failed,
30 failed
31 );
32
33 if failed > 0 {
34 earlyprintln!("\x1b[91mSome tests failed!\x1b[0m");
35 shutdown(true);
36 } else {
37 earlyprintln!("\x1b[32mAll tests passed!\x1b[0m");
38 shutdown(false);
39 }
40}
41
42pub fn run_early_tests() {
43 unsafe extern "C" {
45 static __early_test_start: extern "C" fn();
46 static __early_test_end: extern "C" fn();
47 }
48
49 let start = unsafe { &__early_test_start as *const _ as *const extern "C" fn() };
53 let end = unsafe { &__early_test_end as *const _ as *const extern "C" fn() };
54
55 let count = unsafe { end.offset_from(start) } as usize;
57 if count == 0 {
58 earlyprintln!("\x1b[36m[early_test] No early tests to run.\x1b[0m");
59 return;
60 }
61
62 earlyprintln!(
63 "\n\x1b[36m--- Running {} early tests (pre-mm) ---\x1b[0m",
64 count
65 );
66
67 for i in 0..count {
69 let test_fn = unsafe { *start.add(i) };
70 test_fn();
71 }
72
73 earlyprintln!("\x1b[36m--- Early tests finished ---\x1b[0m\n");
74}
75
76pub struct InterruptGuard {
83 was_enabled: bool,
86}
87
88impl InterruptGuard {
89 #[inline(always)]
95 pub fn new() -> Self {
96 let was_enabled = are_interrupts_enabled();
98 unsafe {
100 enable_interrupts();
101 }
102 Self { was_enabled }
103 }
104}
105
106impl Drop for InterruptGuard {
107 #[inline(always)]
108 fn drop(&mut self) {
109 if !self.was_enabled {
110 unsafe {
112 disable_interrupts();
113 }
114 }
115 }
117}
118
119#[cfg(test)]
120mod tests {
121 #[cfg(target_arch = "riscv64")]
122 use riscv::interrupt::Interrupt;
123
124 use crate::{early_test, kassert, println, test_case};
125
126 test_case!(trivial_assertion, {
127 kassert!(0 != 1);
128 });
129
130 early_test!(exampe_early_test, {
131 kassert!(1 == 1);
132 });
133
134 }