From 26a7561196674b39f9adadcb374f36c503361adb Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Sat, 9 Nov 2019 15:11:50 +0100 Subject: Add basic tests --- kernel/.cargo/config | 2 +- kernel/run | 4 ++-- kernel/src/asm/boot.asm | 3 ++- kernel/src/lib.rs | 11 +++++++-- kernel/src/linker.ld | 5 ++-- kernel/src/main.rs | 32 ++++--------------------- kernel/src/testing/mod.rs | 2 ++ kernel/src/testing/panic.rs | 53 +++++++++++++++--------------------------- kernel/src/testing/runner.rs | 20 +++++++--------- kernel/tests/boot.rs | 38 ++++++++++++++++++++++++++++++ kernel/tests/int3.rs | 32 +++++++++++++++++++++++++ kernel/tests/stack_overflow.rs | 37 +++++++++++++++++++++++++++++ kernel/tests/test01.rs | 25 -------------------- 13 files changed, 157 insertions(+), 107 deletions(-) create mode 100644 kernel/tests/boot.rs create mode 100644 kernel/tests/int3.rs create mode 100644 kernel/tests/stack_overflow.rs delete mode 100644 kernel/tests/test01.rs diff --git a/kernel/.cargo/config b/kernel/.cargo/config index b74f97c..17dbb96 100644 --- a/kernel/.cargo/config +++ b/kernel/.cargo/config @@ -3,4 +3,4 @@ target = "x86_64-uff.json" rustflags = ["-Clink-arg=-r","-Clink-dead-code"] [target.'cfg(target_os = "none")'] -runner = "./run test -test" +runner = "./run test -test" diff --git a/kernel/run b/kernel/run index f9c8df3..26eae12 100755 --- a/kernel/run +++ b/kernel/run @@ -67,7 +67,7 @@ prepare_iso() { } build_iso() { - ld -n -o "$iso_path/isofiles/boot/kernel.bin" -gc-sections -T "$link_script" "$obj_path"/*.o "$(get_rust_bin)" + ld -n -s -o "$iso_path/isofiles/boot/kernel.bin" -gc-sections -T "$link_script" "$obj_path"/*.o "$(get_rust_bin)" grub-mkrescue -d /usr/lib/grub/i386-pc -o "$iso_path/$name.iso" "$iso_path/isofiles" &> /dev/null echo "$kernel_libary" } @@ -92,7 +92,7 @@ run() { "x86_64") qemu="qemu-system-x86_64 -cdrom $iso_path/$name.iso" if $test_mode; then - qemu="$qemu -device isa-debug-exit,iobase=0xf4,iosize=0x04 -serial stdio" + qemu="$qemu -device isa-debug-exit,iobase=0xf4,iosize=0x04 -serial stdio -no-reboot " if $serial_mode; then qemu="$qemu -display none" fi diff --git a/kernel/src/asm/boot.asm b/kernel/src/asm/boot.asm index 2ecaba8..9964636 100644 --- a/kernel/src/asm/boot.asm +++ b/kernel/src/asm/boot.asm @@ -166,7 +166,8 @@ p3_table: resb 4096 p2_table: resb 4096 + alignb 4096 * 512 ; align memory into huge memory page stack_bottom: - resb 4096 * 512 + resb 4096 * 64 stack_top: diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index e5ab3d3..52d41ed 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -19,11 +19,18 @@ pub use qemu::*; #[cfg(test)] #[no_mangle] pub extern "C" fn _start() -> ! { + init(); + test_main(); loop {} } #[cfg(test)] #[panic_handler] -fn panic(_info: &core::panic::PanicInfo) -> ! { - loop {} +fn panic(info: &core::panic::PanicInfo) -> ! { + testing::serial_panic(info) +} + +pub fn init() { + interrupts::gdt::init(); + interrupts::table::init(); } diff --git a/kernel/src/linker.ld b/kernel/src/linker.ld index cca621e..ab508e5 100644 --- a/kernel/src/linker.ld +++ b/kernel/src/linker.ld @@ -5,7 +5,7 @@ SECTIONS { .boot : { - /* ensure that the multiboot heater is at the beginning */ + /* ensure that the multiboot header is at the beginning */ KEEP(*(.multiboot_header)) } @@ -19,7 +19,8 @@ SECTIONS { } .bss : { - *(.bss) + *kernel*(.bss) + *boot.o(.bss) } /*[Guard page]*/ . += 2M; diff --git a/kernel/src/main.rs b/kernel/src/main.rs index ae78c93..bb1dcec 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -3,8 +3,7 @@ #![feature(custom_test_frameworks)] #![feature(abi_x86_interrupt)] #![feature(panic_info_message)] -#![test_runner(crate::testing::serial_test_runner)] -#![reexport_test_harness_main = "test_main"] +#![test_runner(crate::testing::test_runner)] #![no_std] pub mod interrupts; @@ -16,43 +15,20 @@ pub use io::qemu::{exit_qemu, QemuExitCode}; pub use io::vga_text::OStream; pub use io::{qemu, serial, vga_text}; -#[cfg(not(test))] #[no_mangle] extern "C" fn _start() -> ! { - interrupts::gdt::init(); - interrupts::table::init(); + kernel::init(); if cfg!(test) { - #[cfg(test)] - test_main(); qemu::exit_qemu(qemu::QemuExitCode::Success); } - - x86_64::instructions::interrupts::int3(); - - /// TODO: write test - ///fn _loop(i: u64) -> u64 { - /// if i > 0b1010101001101101 { - /// return i; - /// } - /// let n = i; - /// let mut stdout = OStream::new(); - /// write!(&mut stdout, "{:x}", &n as *const u64 as u64).unwrap(); - /// _loop(i + 1) - ///} - ///_loop(0); - /// TODO: write test - ///x86_64::instructions::interrupts::int3(); loop {} } #[panic_handler] #[no_mangle] extern "C" fn panic_handler(info: &core::panic::PanicInfo) -> ! { - io::panic_screen::show(info.message()); - if cfg!(test) { - write!(serial::SerialStream::new(), "Testing failed\n").unwrap(); - qemu::exit_qemu(qemu::QemuExitCode::Failed); + testing::serial_panic(info); } - loop {} + testing::panic(info); } diff --git a/kernel/src/testing/mod.rs b/kernel/src/testing/mod.rs index e328433..f9622bd 100644 --- a/kernel/src/testing/mod.rs +++ b/kernel/src/testing/mod.rs @@ -1,3 +1,5 @@ +pub mod panic; pub mod runner; +pub use panic::{panic, serial_panic, serial_should_panic, should_panic}; pub use runner::{serial_test_runner, serial_test_runner_panic, test_runner, test_runner_panic}; diff --git a/kernel/src/testing/panic.rs b/kernel/src/testing/panic.rs index 7fb769b..729a45f 100644 --- a/kernel/src/testing/panic.rs +++ b/kernel/src/testing/panic.rs @@ -1,51 +1,36 @@ use crate::io::{qemu, serial, vga_text}; use core::fmt::Write; +use core::panic::PanicInfo; use qemu::{exit_qemu, QemuExitCode}; use serial::SerialStream; use vga_text::OStream; -#[cfg(test)] -pub fn serial_test_runner_panic(tests: &[&dyn Fn()]) { +pub fn serial_should_panic(info: &PanicInfo) -> ! { let mut stdout = SerialStream::new(); - write!(stdout, "Running {} tests", tests.len()).unwrap(); - for test in tests { - test(); - write!(stdout, "[test did not panic]").unwrap(); - exit_qemu(QemuExitCode::Failed); - } + write!(stdout, "\nOK\nsuccessfully panicked\n").unwrap(); exit_qemu(QemuExitCode::Success); + loop {} } -#[cfg(test)] -pub fn serial_test_runner(tests: &[&dyn Fn()]) { +pub fn serial_panic(info: &PanicInfo) -> ! { + crate::io::panic_screen::show(info.message()); let mut stdout = SerialStream::new(); - write!(stdout, "Running {} tests", tests.len()).unwrap(); - for test in tests { - test(); - write!(stdout, "[test did not panic]").unwrap(); - } - exit_qemu(QemuExitCode::Success); + write!( + stdout, + "\nERR\nPanicked execute without -serial for more details\n{}", + info + ) + .unwrap(); + exit_qemu(QemuExitCode::Failed); + loop {} } -#[cfg(test)] -pub fn test_runner_panic(tests: &[&dyn Fn()]) { - let mut stdout = OStream::new(); - write!(stdout, "Running {} tests", tests.len()).unwrap(); - for test in tests { - test(); - write!(stdout, "[test did not panic]").unwrap(); - exit_qemu(QemuExitCode::Failed); - } +pub fn should_panic(_info: &PanicInfo) -> ! { exit_qemu(QemuExitCode::Success); + loop {} } -#[cfg(test)] -pub fn test_runner(tests: &[&dyn Fn()]) { - let mut stdout = OStream::new(); - write!(stdout, "Running {} tests", tests.len()).unwrap(); - for test in tests { - test(); - write!(stdout, "[test did not panic]").unwrap(); - } - exit_qemu(QemuExitCode::Success); +pub fn panic(info: &PanicInfo) -> ! { + crate::io::panic_screen::show(info.message()); + loop {} } diff --git a/kernel/src/testing/runner.rs b/kernel/src/testing/runner.rs index 0f9d08b..38d6d94 100644 --- a/kernel/src/testing/runner.rs +++ b/kernel/src/testing/runner.rs @@ -4,48 +4,44 @@ use qemu::{exit_qemu, QemuExitCode}; use serial::SerialStream; use vga_text::OStream; -//#[cfg(test)] pub fn serial_test_runner_panic(tests: &[&dyn Fn()]) { let mut stdout = SerialStream::new(); - write!(stdout, "Running {} tests", tests.len()).unwrap(); + write!(stdout, "\nRunning {} tests\n", tests.len()).unwrap(); for test in tests { test(); - write!(stdout, "[test did not panic]").unwrap(); + write!(stdout, "\n[test did not panic]\n\n").unwrap(); exit_qemu(QemuExitCode::Failed); } exit_qemu(QemuExitCode::Success); } -//#[cfg(test)] pub fn serial_test_runner(tests: &[&dyn Fn()]) { let mut stdout = SerialStream::new(); - write!(stdout, "Running {} tests", tests.len()).unwrap(); + write!(stdout, "\nRunning {} tests\n", tests.len()).unwrap(); for test in tests { test(); - write!(stdout, "[test did not panic]").unwrap(); + write!(stdout, "\n[OK]\n").unwrap(); } exit_qemu(QemuExitCode::Success); } -//#[cfg(test)] pub fn test_runner_panic(tests: &[&dyn Fn()]) { let mut stdout = OStream::new(); - write!(stdout, "Running {} tests", tests.len()).unwrap(); + write!(stdout, "\nRunning {} tests\n", tests.len()).unwrap(); for test in tests { test(); - write!(stdout, "[test did not panic]").unwrap(); + write!(stdout, "\n[test did not panic]\n\n").unwrap(); exit_qemu(QemuExitCode::Failed); } exit_qemu(QemuExitCode::Success); } -//#[cfg(test)] pub fn test_runner(tests: &[&dyn Fn()]) { let mut stdout = OStream::new(); - write!(stdout, "Running {} tests", tests.len()).unwrap(); + write!(stdout, "\nRunning {} tests\n", tests.len()).unwrap(); for test in tests { test(); - write!(stdout, "[test did not panic]").unwrap(); + write!(stdout, "\n[OK]\n").unwrap(); } exit_qemu(QemuExitCode::Success); } diff --git a/kernel/tests/boot.rs b/kernel/tests/boot.rs new file mode 100644 index 0000000..534199a --- /dev/null +++ b/kernel/tests/boot.rs @@ -0,0 +1,38 @@ +#![no_main] +#![feature(compiler_builtins_lib)] +#![feature(custom_test_frameworks)] +#![feature(abi_x86_interrupt)] +#![feature(panic_info_message)] +#![test_runner(kernel::testing::serial_test_runner)] +#![reexport_test_harness_main = "test_main"] +#![no_std] + +use kernel; +use kernel::io::qemu; + +#[no_mangle] +extern "C" fn _start() -> ! { + kernel::init(); + test_main(); + + loop {} +} + +#[test_case] +fn boot() { + assert!(true) +} + +#[test_case] +fn poweroff() { + qemu::exit_qemu(qemu::QemuExitCode::Success); + panic!("Qemu did not exit"); +} + +#[cfg(test)] +#[panic_handler] +#[no_mangle] +extern "C" fn panic_handler(info: &core::panic::PanicInfo) -> ! { + kernel::testing::serial_panic(info); + loop {} +} diff --git a/kernel/tests/int3.rs b/kernel/tests/int3.rs new file mode 100644 index 0000000..771c17d --- /dev/null +++ b/kernel/tests/int3.rs @@ -0,0 +1,32 @@ +#![no_main] +#![feature(compiler_builtins_lib)] +#![feature(custom_test_frameworks)] +#![feature(abi_x86_interrupt)] +#![feature(panic_info_message)] +#![test_runner(kernel::testing::serial_test_runner)] +#![reexport_test_harness_main = "test_main"] +#![no_std] + +use kernel; +use kernel::io::qemu; + +#[no_mangle] +extern "C" fn _start() -> ! { + kernel::init(); + test_main(); + + loop {} +} + +#[test_case] +fn breakpoint() { + x86_64::instructions::interrupts::int3(); +} + +#[cfg(test)] +#[panic_handler] +#[no_mangle] +extern "C" fn panic_handler(info: &core::panic::PanicInfo) -> ! { + kernel::testing::serial_should_panic(info); + loop {} +} diff --git a/kernel/tests/stack_overflow.rs b/kernel/tests/stack_overflow.rs new file mode 100644 index 0000000..677a9e1 --- /dev/null +++ b/kernel/tests/stack_overflow.rs @@ -0,0 +1,37 @@ +#![no_main] +#![feature(compiler_builtins_lib)] +#![feature(custom_test_frameworks)] +#![feature(abi_x86_interrupt)] +#![feature(panic_info_message)] +#![test_runner(kernel::testing::serial_test_runner_panic)] +#![no_std] + +use core::fmt::Write; +use kernel; +use kernel::io::qemu; + +#[no_mangle] +extern "C" fn _start() -> ! { + kernel::init(); + _loop(0); + + loop {} +} + +fn _loop(i: u128) -> u128 { + if i > 1u128 << 83 { + return i; + } + let n = i; + let mut stdout = kernel::OStream::new(); + write!(&mut stdout, "{:x}", &n as *const u128 as u128).unwrap(); + _loop(i + 1) +} + +#[cfg(test)] +#[panic_handler] +#[no_mangle] +extern "C" fn panic_handler(info: &core::panic::PanicInfo) -> ! { + kernel::testing::serial_should_panic(info); + loop {} +} diff --git a/kernel/tests/test01.rs b/kernel/tests/test01.rs deleted file mode 100644 index 933d689..0000000 --- a/kernel/tests/test01.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![no_main] -#![feature(compiler_builtins_lib)] -#![feature(custom_test_frameworks)] -#![feature(abi_x86_interrupt)] -#![feature(panic_info_message)] -#![test_runner(crate::testing::serial_test_runner)] -#![no_std] - -use kernel; -use kernel::io::qemu; - -#[no_mangle] -extern "C" fn _start() -> ! { - kernel::io::panic_screen::show(Some(&format_args!("hey bro"))); - - - loop {} -} - -#[cfg(test)] -#[panic_handler] -#[no_mangle] -extern "C" fn panic_handler(info: &core::panic::PanicInfo) -> ! { - loop {} -} -- cgit v1.2.3-54-g00ecf