testing
This commit is contained in:
parent
fc9fc22261
commit
bbe0551ac5
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
/.direnv/
|
||||
/kernel/qemu.log
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <<EOF
|
||||
timeout: 0
|
||||
serial: yes
|
||||
serial_baudrate: 9600
|
||||
|
||||
/Kernel
|
||||
protocol: limine
|
||||
|
|
@ -39,10 +64,22 @@ EOF
|
|||
mcopy -i "$image" "$limine_uefi_path" ::/EFI/BOOT/BOOTX64.EFI
|
||||
fi
|
||||
|
||||
# cp -n "$OVMF_PATH/FV/OVMF_VARS.fd" "$parent/$bin_name.OVMF_VARS.fd"
|
||||
|
||||
set +e
|
||||
|
||||
qemu-system-x86_64 \
|
||||
-drive file="$image",format=raw \
|
||||
-machine q35,accel=kvm -enable-kvm \
|
||||
-drive if=pflash,format=raw,readonly=on,file="$OVMF_PATH/FV/OVMF_CODE.fd" \
|
||||
-serial stdio \
|
||||
-vga std
|
||||
-chardev stdio,id=serial0,logfile=qemu.log,signal=off \
|
||||
-serial chardev:serial0 \
|
||||
-vga std \
|
||||
${QEMU_TEST_ARGS[@]}
|
||||
|
||||
qemu_ret=$?
|
||||
|
||||
if [[ $is_test -eq 1 ]]; then
|
||||
exit $([ $qemu_ret -eq 33 ])
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
#![no_std]
|
||||
#![feature(const_trait_impl, const_default)]
|
||||
#![cfg_attr(test, feature(custom_test_frameworks))]
|
||||
#![cfg_attr(test, test_runner(crate::tests::test_runner))]
|
||||
#![cfg_attr(test, no_main)]
|
||||
#![cfg_attr(test, reexport_test_harness_main = "test_main")]
|
||||
|
||||
pub mod limine;
|
||||
pub mod serial;
|
||||
pub mod sync;
|
||||
pub mod x86_64;
|
||||
|
||||
pub mod testing;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// # Safety
|
||||
pub unsafe fn volatile_copy<T: Sized>(src: *const T, dst: *mut T, count: usize) {
|
||||
unsafe {
|
||||
|
|
|
|||
37
kernel/src/testing.rs
Normal file
37
kernel/src/testing.rs
Normal file
|
|
@ -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<T> Testable for T
|
||||
where
|
||||
T: Fn(),
|
||||
{
|
||||
fn run(&self) {
|
||||
crate::serial_print!("{}...\t", core::any::type_name::<T>());
|
||||
self();
|
||||
crate::serial_println!("[ok]");
|
||||
}
|
||||
}
|
||||
26
kernel/src/tests.rs
Normal file
26
kernel/src/tests.rs
Normal file
|
|
@ -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");
|
||||
// }
|
||||
13
kernel/tests/simple.rs
Normal file
13
kernel/tests/simple.rs
Normal file
|
|
@ -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)
|
||||
}
|
||||
Loading…
Reference in a new issue