From a3005ff146357006a712fab7ca558af50f3bbb40 Mon Sep 17 00:00:00 2001 From: clizia Date: Sun, 31 Aug 2025 21:26:59 +0200 Subject: [PATCH 1/3] integration testing --- src/lib.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 65 +++------------------------------------ tests/basic_boot.rs | 19 ++++++++++++ 3 files changed, 98 insertions(+), 61 deletions(-) create mode 100644 src/lib.rs create mode 100644 tests/basic_boot.rs diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..5bfdcf0 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,75 @@ +#![no_std] +#![cfg_attr(test, no_main)] +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] + +use core::panic::PanicInfo; + +pub mod vga_buffer; +pub mod serial; + +pub trait Testable { + fn run(&self) -> (); +} + +impl Testable for T +where + T: Fn(), +{ + fn run(&self) -> () { + serial_print!("{}...\t", core::any::type_name::()); + self(); + serial_println!("[ok]"); + } +} + +pub fn test_runner(tests: &[&dyn Testable]) { + serial_println!("Running {} tests", tests.len()); + + for test in tests { + test.run(); + } + + exit_qemu(QemuExitCode::Success); +} + +pub fn test_panic_handler(info: &PanicInfo) -> ! { + serial_println!("[failed]\n"); + serial_println!("Error: {}\n", info); + exit_qemu(QemuExitCode::Failed); + + loop {} +} + +/// entry point for `cargo test` +#[cfg(test)] +#[unsafe(no_mangle)] +pub extern "C" fn _start() -> ! { + test_main(); + + loop {} +} + +#[cfg(test)] +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + test_panic_handler(info); +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u32)] +pub enum QemuExitCode { + Success = 0x10, + Failed = 0x11, +} + +pub fn exit_qemu(exit_code: QemuExitCode) { + use x86_64::instructions::port::Port; + + unsafe { + let mut port = Port::new(0xF4); + port.write(exit_code as u32); + } +} + diff --git a/src/main.rs b/src/main.rs index 3a03d35..db86ade 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,47 +1,15 @@ #![no_std] // dont link the standard library #![no_main] // disable all rust-level entry points #![feature(custom_test_frameworks)] -#![test_runner(crate::test_runner)] +#![test_runner(totos::test_runner)] #![reexport_test_harness_main = "test_main"] use core::panic::PanicInfo; +use totos::println; -mod vga_buffer; -mod serial; - -pub trait Testable { - fn run(&self) -> (); -} - -impl Testable for T -where - T: Fn(), -{ - fn run(&self) -> () { - serial_print!("{}...\t", core::any::type_name::()); - self(); - serial_println!("[ok]"); - } -} - +// this is here because i dont want to remove it :> static HELLO: &[u8] = b"Hello toto :3"; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(u32)] -pub enum QemuExitCode { - Success = 0x10, - Failed = 0x11, -} - -pub fn exit_qemu(exit_code: QemuExitCode) { - use x86_64::instructions::port::Port; - - unsafe { - let mut port = Port::new(0xF4); - port.write(exit_code as u32); - } -} - // this function is the entry point since the linker // looks for a function named `_start` by default #[unsafe(no_mangle)] @@ -54,35 +22,10 @@ pub extern "C" fn _start() -> ! { loop {} } -// panic handler -#[cfg(not(test))] -#[panic_handler] -fn panic(info: &PanicInfo) -> ! { - println!("{}", info); - - loop {} -} - -// panic handler in test mode #[cfg(test)] #[panic_handler] fn panic(info: &PanicInfo) -> ! { - serial_println!("[failed]\n"); - serial_println!("Error: {}\n", info); - exit_qemu(QemuExitCode::Failed); - - loop {} -} - -#[cfg(test)] -pub fn test_runner(tests: &[&dyn Testable]) { - serial_println!("Running {} tests", tests.len()); - - for test in tests { - test.run(); - } - - exit_qemu(QemuExitCode::Success); + totos::test_panic_handler(info) } #[test_case] diff --git a/tests/basic_boot.rs b/tests/basic_boot.rs new file mode 100644 index 0000000..cfa33ec --- /dev/null +++ b/tests/basic_boot.rs @@ -0,0 +1,19 @@ +#![no_std] +#![no_main] +#![feature(custom_test_frameworks)] +#![test_runner(totos::test_runner)] +#![reexport_test_harness_main = "test_main"] + +use core::panic::PanicInfo; + +#[unsafe(no_mangle)] +pub extern "C" fn _start() -> ! { + test_main(); + + loop {} +} + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + totos::test_panic_handler(info) +} From 48f84b895b1a32039c406c4e05d394df9a9e4793 Mon Sep 17 00:00:00 2001 From: clizia Date: Sun, 31 Aug 2025 21:28:00 +0200 Subject: [PATCH 2/3] integration testing 2 --- tests/basic_boot.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/basic_boot.rs b/tests/basic_boot.rs index cfa33ec..79ce882 100644 --- a/tests/basic_boot.rs +++ b/tests/basic_boot.rs @@ -5,6 +5,7 @@ #![reexport_test_harness_main = "test_main"] use core::panic::PanicInfo; +use totos::println; #[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { @@ -17,3 +18,8 @@ pub extern "C" fn _start() -> ! { fn panic(info: &PanicInfo) -> ! { totos::test_panic_handler(info) } + +#[test_case] +fn test_println() { + println!("test_println_output"); +} From caa6e8e9513bfa3af6132571639e0f0cf95a12b5 Mon Sep 17 00:00:00 2001 From: clizia Date: Sun, 31 Aug 2025 21:36:35 +0200 Subject: [PATCH 3/3] fix: integration testing --- Cargo.toml | 1 - src/lib.rs | 2 +- src/main.rs | 9 +++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 408fd74..5b7bef3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,4 +36,3 @@ test-args = [ "none", ] test-success-exit-code = 33 # (0x10 << 1) | 1 = 33 -test-timeout = "300" # in seconds diff --git a/src/lib.rs b/src/lib.rs index 5bfdcf0..727bdfe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,7 +54,7 @@ pub extern "C" fn _start() -> ! { #[cfg(test)] #[panic_handler] fn panic(info: &PanicInfo) -> ! { - test_panic_handler(info); + test_panic_handler(info) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/main.rs b/src/main.rs index db86ade..579ad9c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,15 @@ pub extern "C" fn _start() -> ! { loop {} } +/// this function is called on panic +#[cfg(not(test))] +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + println!("{}", info); + + loop {} +} + #[cfg(test)] #[panic_handler] fn panic(info: &PanicInfo) -> ! {