From a264264f17b8beda0be4a64cddb565a49551c013 Mon Sep 17 00:00:00 2001 From: YushiOMOTE Date: Sat, 13 Jul 2024 09:49:48 +0900 Subject: [PATCH] Add CI to run integration test --- .github/workflows/main.yml | 22 ++++++++++ testing/.cargo/config.toml | 6 +++ testing/Cargo.toml | 28 ++++++++++++ rust-toolchain => testing/rust-toolchain | 0 testing/src/lib.rs | 54 ++++++++++++++++++++++++ testing/tests/basic.rs | 16 +++++++ 6 files changed, 126 insertions(+) create mode 100644 testing/.cargo/config.toml create mode 100644 testing/Cargo.toml rename rust-toolchain => testing/rust-toolchain (100%) create mode 100644 testing/src/lib.rs create mode 100644 testing/tests/basic.rs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b3fab2b..deeefb9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,6 +19,28 @@ jobs: rustup default ${{ matrix.rust }} - run: cargo test --verbose + integration-test: + runs-on: ubuntu-latest + defaults: + run: + working-directory: testing + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install Qemu + run: | + sudo apt update + sudo apt install qemu-system + - name: Install Rust + run: | + rustup update nightly --no-self-update + rustup default nightly + rustup target add x86_64-unknown-none + rustup component add rust-src + rustup component add llvm-tools-preview + - run: cargo test --verbose + fmt: runs-on: ubuntu-latest steps: diff --git a/testing/.cargo/config.toml b/testing/.cargo/config.toml new file mode 100644 index 0000000..5c19ef0 --- /dev/null +++ b/testing/.cargo/config.toml @@ -0,0 +1,6 @@ +[build] +target = "x86_64-unknown-none" +rustflags = ["-Crelocation-model=static"] + +[target.'cfg(target_os = "none")'] +runner = "bootimage runner" diff --git a/testing/Cargo.toml b/testing/Cargo.toml new file mode 100644 index 0000000..85ef829 --- /dev/null +++ b/testing/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "testing" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[[test]] +name = "basic" +harness = false + +[dependencies] +bootloader = "0.9.10" +uart_16550 = "0.2.8" +spin = "0.5.0" +x86_64 = "0.15.1" +com_logger = { path = ".." } +log = "0.4.22" + +[dependencies.lazy_static] +version = "1.3.0" +features = ["spin_no_std"] + +[package.metadata.bootimage] +test-args = [ + "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-serial", "stdio", + "-display", "none" +] +test-success-exit-code = 33 diff --git a/rust-toolchain b/testing/rust-toolchain similarity index 100% rename from rust-toolchain rename to testing/rust-toolchain diff --git a/testing/src/lib.rs b/testing/src/lib.rs new file mode 100644 index 0000000..0b86fef --- /dev/null +++ b/testing/src/lib.rs @@ -0,0 +1,54 @@ +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] +#![no_std] +#![no_main] + +use core::panic::PanicInfo; +use log::error; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u32)] +pub enum QemuExitCode { + Success = 0x10, + Failed = 0x11, +} + +pub fn exit() { + exit_qemu(QemuExitCode::Success) +} + +pub fn exit_qemu(exit_code: QemuExitCode) { + use x86_64::instructions::port::PortWriteOnly; + + unsafe { + let mut port = PortWriteOnly::new(0xf4); + port.write(exit_code as u32); + } +} + +pub fn test_runner(tests: &[&dyn Fn()]) { + for test in tests { + test(); + } + exit_qemu(QemuExitCode::Success); +} + +pub fn test_panic_handler(info: &PanicInfo) -> ! { + error!("{:#?}", info); + exit_qemu(QemuExitCode::Failed); + loop {} +} + +#[cfg(test)] +#[no_mangle] +pub extern "C" fn _start() -> ! { + test_main(); + loop {} +} + +#[cfg(test)] +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + test_panic_handler(info) +} diff --git a/testing/tests/basic.rs b/testing/tests/basic.rs new file mode 100644 index 0000000..066ff00 --- /dev/null +++ b/testing/tests/basic.rs @@ -0,0 +1,16 @@ +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +#[no_mangle] // don't mangle the name of this function +pub extern "C" fn _start() { + com_logger::init(); + log::info!("Hello world"); + testing::exit(); +} + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + testing::test_panic_handler(info) +}