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 new file mode 100644 index 0000000..727bdfe --- /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..579ad9c 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,7 +22,7 @@ pub extern "C" fn _start() -> ! { loop {} } -// panic handler +/// this function is called on panic #[cfg(not(test))] #[panic_handler] fn panic(info: &PanicInfo) -> ! { @@ -63,26 +31,10 @@ fn panic(info: &PanicInfo) -> ! { 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..79ce882 --- /dev/null +++ b/tests/basic_boot.rs @@ -0,0 +1,25 @@ +#![no_std] +#![no_main] +#![feature(custom_test_frameworks)] +#![test_runner(totos::test_runner)] +#![reexport_test_harness_main = "test_main"] + +use core::panic::PanicInfo; +use totos::println; + +#[unsafe(no_mangle)] +pub extern "C" fn _start() -> ! { + test_main(); + + loop {} +} + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + totos::test_panic_handler(info) +} + +#[test_case] +fn test_println() { + println!("test_println_output"); +}