From bbe0551ac5e8786c28d4c7c0929e62fdac9ee714 Mon Sep 17 00:00:00 2001 From: janis Date: Sun, 19 Jul 2026 13:15:10 +0200 Subject: [PATCH] testing --- .gitignore | 1 + kernel/Cargo.toml | 6 +++++- kernel/build.rs | 5 +++-- kernel/run.sh | 47 +++++++++++++++++++++++++++++++++++++----- kernel/src/lib.rs | 8 +++++++ kernel/src/testing.rs | 37 +++++++++++++++++++++++++++++++++ kernel/src/tests.rs | 26 +++++++++++++++++++++++ kernel/tests/simple.rs | 13 ++++++++++++ 8 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 kernel/src/testing.rs create mode 100644 kernel/src/tests.rs create mode 100644 kernel/tests/simple.rs diff --git a/.gitignore b/.gitignore index 29963da..6884187 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /.direnv/ +/kernel/qemu.log diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index a6c1c0b..ad92720 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -10,8 +10,12 @@ test = false bench = false [lib] -test = false +test = true bench = false +[[test]] +name = "simple" +harness = false + [dependencies] bitflags = "2.13.1" diff --git a/kernel/build.rs b/kernel/build.rs index 373fd84..a4f5cd9 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -1,6 +1,7 @@ fn main() { println!("cargo::rerun-if-changed=build.rs"); - - println!("cargo::rustc-link-arg-bin=kernel=-Tkernel.lds"); println!("cargo::rerun-if-changed=kernel.lds"); + + println!("cargo::rustc-link-arg=-Tkernel.lds"); + // println!("cargo::rustc-link-arg-tests=-Tkernel.lds"); } diff --git a/kernel/run.sh b/kernel/run.sh index 71a549d..dab2f71 100755 --- a/kernel/run.sh +++ b/kernel/run.sh @@ -8,16 +8,41 @@ canonicalised="$(realpath -- "$bin")" parent="$(dirname -- "$canonicalised")" bin_name="$(basename -- "$canonicalised")" -image="$parent/$bin_name.img" +parent_base="$(basename -- "$parent")" +case "$parent_base" in + rustdoctest*) + is_doctest=1 + ;; + *) + is_doctest=0 + ;; +esac + +case "$parent" in + */deps|*/deps/) + is_test=1 + ;; + *) + is_test=$is_doctest + ;; +esac + +echo "Running $bin_name (is_test=$is_test, is_doctest=$is_doctest)" + +if [[ $is_test -eq 1 ]]; then + QEMU_TEST_ARGS=("-display" "none" "-device" "isa-debug-exit,iobase=0xf4,iosize=0x04") +else + QEMU_TEST_ARGS=() +fi + +image="$parent/$bin_name.img" if [[ "$canonicalised" -nt "$image" ]]; then echo "Creating image $image" cat > /tmp/limine.conf <(src: *const T, dst: *mut T, count: usize) { unsafe { diff --git a/kernel/src/testing.rs b/kernel/src/testing.rs new file mode 100644 index 0000000..ec0ef7e --- /dev/null +++ b/kernel/src/testing.rs @@ -0,0 +1,37 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u16)] +pub enum QemuExitCode { + Success = 0x10, + Failed = 0x11, +} + +pub fn exit_qemu(exit_code: QemuExitCode) -> ! { + use crate::x86_64::PortU16; + + unsafe { + let port = PortU16(0xf4); + port.write(exit_code as u16); + } + + crate::x86_64::halt_loop() +} + +pub fn test_panic_handler(info: &core::panic::PanicInfo) -> ! { + crate::serial_println!("[PANIC] {}", info); + exit_qemu(QemuExitCode::Failed) +} + +pub trait Testable { + fn run(&self); +} + +impl Testable for T +where + T: Fn(), +{ + fn run(&self) { + crate::serial_print!("{}...\t", core::any::type_name::()); + self(); + crate::serial_println!("[ok]"); + } +} diff --git a/kernel/src/tests.rs b/kernel/src/tests.rs new file mode 100644 index 0000000..c19763a --- /dev/null +++ b/kernel/src/tests.rs @@ -0,0 +1,26 @@ +use crate::testing::{QemuExitCode, Testable, exit_qemu}; + +pub fn test_runner(tests: &[&dyn Testable]) { + crate::serial_println!("Running {} tests", tests.len()); + for test in tests { + test.run(); + } + + crate::serial_println!("[ok] All tests passed"); +} + +#[panic_handler] +fn panic_thunk(info: &core::panic::PanicInfo) -> ! { + crate::testing::test_panic_handler(info) +} + +#[unsafe(export_name = "_start")] +fn main() -> ! { + crate::test_main(); + exit_qemu(QemuExitCode::Success) +} + +// #[test_case] +// fn panics() { +// panic!("This test should panic"); +// } diff --git a/kernel/tests/simple.rs b/kernel/tests/simple.rs new file mode 100644 index 0000000..7f9cd03 --- /dev/null +++ b/kernel/tests/simple.rs @@ -0,0 +1,13 @@ +#![no_main] +#![no_std] + +#[unsafe(export_name = "_start")] +pub extern "C" fn main() -> ! { + kernel::serial_println!("Hello, world!"); + kernel::testing::exit_qemu(kernel::testing::QemuExitCode::Success) +} + +#[panic_handler] +fn panic_thunk(info: &core::panic::PanicInfo) -> ! { + kernel::testing::test_panic_handler(info) +}