Skip to content

Commit 06b4881

Browse files
committed
Add failing unit tests
1 parent 4008438 commit 06b4881

File tree

8 files changed

+133
-0
lines changed

8 files changed

+133
-0
lines changed

Diff for: Cargo.lock

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ members = [
2323
"tests/test_kernels/higher_half",
2424
"tests/test_kernels/pie",
2525
"tests/test_kernels/lto",
26+
"tests/test_kernels/ramdisk"
2627
]
2728
exclude = ["examples/basic", "examples/test_framework"]
2829

@@ -50,6 +51,7 @@ test_kernel_default_settings = { path = "tests/test_kernels/default_settings", a
5051
test_kernel_higher_half = { path = "tests/test_kernels/higher_half", artifact = "bin", target = "x86_64-unknown-none" }
5152
test_kernel_map_phys_mem = { path = "tests/test_kernels/map_phys_mem", artifact = "bin", target = "x86_64-unknown-none" }
5253
test_kernel_pie = { path = "tests/test_kernels/pie", artifact = "bin", target = "x86_64-unknown-none" }
54+
test_kernel_ramdisk = { path = "tests/test_kernels/ramdisk", artifact = "bin", target = "x86_64-unknown-none" }
5355

5456
[profile.dev]
5557
panic = "abort"

Diff for: tests/ramdisk.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use std::path::Path;
2+
3+
use bootloader_test_runner::run_test_kernel;
4+
5+
#[test]
6+
fn basic_boot() {
7+
let ramdisk = Path::new("ramdisk.txt").canonicalize().unwrap();
8+
run_test_kernel(
9+
env!("CARGO_BIN_FILE_TEST_KERNEL_RAMDISK_basic_boot"),
10+
Some(&ramdisk),
11+
);
12+
}
13+
14+
#[test]
15+
fn check_ramdisk() {
16+
let ramdisk = Path::new("ramdisk.txt").canonicalize().unwrap();
17+
run_test_kernel(
18+
env!("CARGO_BIN_FILE_TEST_KERNEL_RAMDISK_ramdisk"),
19+
Some(&ramdisk),
20+
);
21+
}

Diff for: tests/ramdisk.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Test ramdisk.

Diff for: tests/test_kernels/ramdisk/Cargo.toml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "test_kernel_ramdisk"
3+
version = "0.1.0"
4+
authors = ["Philipp Oppermann <[email protected]>"]
5+
edition = "2021"
6+
7+
[dependencies]
8+
bootloader_api = { path = "../../../api" }
9+
x86_64 = { version = "0.14.7", default-features = false, features = [
10+
"instructions",
11+
"inline_asm",
12+
] }
13+
uart_16550 = "0.2.10"

Diff for: tests/test_kernels/ramdisk/src/bin/basic_boot.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![no_std] // don't link the Rust standard library
2+
#![no_main] // disable all Rust-level entry points
3+
4+
use bootloader_api::{entry_point, BootInfo};
5+
use test_kernel_ramdisk::{exit_qemu, QemuExitCode};
6+
7+
entry_point!(kernel_main);
8+
9+
fn kernel_main(_boot_info: &'static mut BootInfo) -> ! {
10+
exit_qemu(QemuExitCode::Success);
11+
}
12+
13+
/// This function is called on panic.
14+
#[panic_handler]
15+
#[cfg(not(test))]
16+
fn panic(info: &core::panic::PanicInfo) -> ! {
17+
use core::fmt::Write;
18+
19+
let _ = writeln!(test_kernel_ramdisk::serial(), "PANIC: {}", info);
20+
exit_qemu(QemuExitCode::Failed);
21+
}

Diff for: tests/test_kernels/ramdisk/src/bin/ramdisk.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![no_std] // don't link the Rust standard library
2+
#![no_main] // disable all Rust-level entry points
3+
4+
use bootloader_api::{entry_point, BootInfo};
5+
use test_kernel_ramdisk::{exit_qemu, QemuExitCode, RAMDISK_CONTENTS};
6+
7+
8+
9+
entry_point!(kernel_main);
10+
11+
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
12+
assert!(boot_info.ramdisk_addr.into_option().is_some());
13+
assert_eq!(boot_info.ramdisk_len as usize, RAMDISK_CONTENTS.len());
14+
15+
let ramdisk = boot_info.ramdisk_addr.into_option().unwrap() as *const u8;
16+
compare_ramdisk_contents(ramdisk);
17+
18+
19+
exit_qemu(QemuExitCode::Success);
20+
}
21+
22+
fn compare_ramdisk_contents(ramdisk: *const u8) {
23+
let expected = RAMDISK_CONTENTS;
24+
for i in 0..expected.len() {
25+
unsafe { assert_eq!(expected[i], *ramdisk.offset(i as isize)); }
26+
}
27+
}
28+
/// This function is called on panic.
29+
#[cfg(not(test))]
30+
#[panic_handler]
31+
fn panic(info: &core::panic::PanicInfo) -> ! {
32+
use core::fmt::Write;
33+
34+
let _ = writeln!(test_kernel_ramdisk::serial(), "PANIC: {}", info);
35+
exit_qemu(QemuExitCode::Failed);
36+
}

Diff for: tests/test_kernels/ramdisk/src/lib.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#![no_std]
2+
3+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4+
#[repr(u32)]
5+
pub enum QemuExitCode {
6+
Success = 0x10,
7+
Failed = 0x11,
8+
}
9+
10+
pub static RAMDISK_CONTENTS: &[u8] = include_bytes!("../../../ramdisk.txt");
11+
12+
pub fn exit_qemu(exit_code: QemuExitCode) -> ! {
13+
use x86_64::instructions::{nop, port::Port};
14+
15+
unsafe {
16+
let mut port = Port::new(0xf4);
17+
port.write(exit_code as u32);
18+
}
19+
20+
loop {
21+
nop();
22+
}
23+
}
24+
25+
pub fn serial() -> uart_16550::SerialPort {
26+
let mut port = unsafe { uart_16550::SerialPort::new(0x3F8) };
27+
port.init();
28+
port
29+
}

0 commit comments

Comments
 (0)