diff --git a/.buildkite/smoke-tests.json b/.buildkite/smoke-tests.json new file mode 100644 index 0000000..aaf2c7d --- /dev/null +++ b/.buildkite/smoke-tests.json @@ -0,0 +1,15 @@ +{ + "tests": [ + { + "test_name": "oxerun: run hello world unikernel", + "command": "cd tests && cargo test test_run_aarch64_smoke_test_in_qemu -- --nocapture", + "soft_fail": "true", + "docker_plugin": { + "privileged": true + }, + "platform": [ + "x86_64" + ] + } + ] +} diff --git a/Cargo.toml b/Cargo.toml index ca077bb..d90006c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,5 @@ exclude = [ "oxerun", "examples/ioctls", "examples/xstore", + "tests", ] diff --git a/oxerun/Dockerfile b/oxerun/Dockerfile new file mode 100644 index 0000000..4d69c00 --- /dev/null +++ b/oxerun/Dockerfile @@ -0,0 +1,165 @@ +# SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +FROM debian:bookworm-slim +RUN <&2 +fi + +if [ ! -f "${DOM0_UNIKERNEL}" ]; then + printf 'DOM0_UNIKERNEL value %s does not exist!\n' "${DOM0_UNIKERNEL}" 1>&2 +fi + +qemu-system-aarch64 \ + -D qemu.log \ + -d guest_errors \ + -machine virt,virtualization=on,gic-version=3 \ + -cpu cortex-a57 \ + -chardev file,id=char0,path="${QEMU_OUTPUT}" \ + -serial chardev:char0 \ + -monitor none \ + -display none \ + -m 8192 \ + -smp 4 \ + -kernel "${XEN_KERNEL}" \ + -append 'dom0_mem=4G loglvl=none guest_loglvl=none sync_console=true' \ + -device guest-loader,addr=0x80000000,kernel="${DOM0_UNIKERNEL}",bootargs='dom0_mem=4G loglvl=none guest_loglvl=none sync_console=true' + +cat > /tmp/expected_output < /dev/null 2>&1; then + diff -w -u /tmp/expected_output "${QEMU_OUTPUT}" + exit 1 +fi + +exit 0 +EOF + +CMD ["/bin/sh", "/run_qemu_oxerun.sh"] diff --git a/rust-vmm-ci b/rust-vmm-ci index 09aef99..8ae03e5 160000 --- a/rust-vmm-ci +++ b/rust-vmm-ci @@ -1 +1 @@ -Subproject commit 09aef997d82ab55022ee20a7962372209ce0c9a8 +Subproject commit 8ae03e5c363f1d6ece883554a69b2fd843620f4b diff --git a/tests/Cargo.toml b/tests/Cargo.toml new file mode 100644 index 0000000..bc59987 --- /dev/null +++ b/tests/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "tests" +authors = ["Manos Pitsidianakis "] +version = "0.1.0" +edition = "2021" +publish = false +license = "Apache-2.0 OR BSD-3-Clause" + +[dependencies] diff --git a/tests/LICENSE-APACHE b/tests/LICENSE-APACHE new file mode 120000 index 0000000..965b606 --- /dev/null +++ b/tests/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/tests/LICENSE-BSD-3-Clause b/tests/LICENSE-BSD-3-Clause new file mode 120000 index 0000000..f2b0791 --- /dev/null +++ b/tests/LICENSE-BSD-3-Clause @@ -0,0 +1 @@ +../LICENSE-BSD-3-Clause \ No newline at end of file diff --git a/tests/rust-toolchain.toml b/tests/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/tests/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/tests/src/lib.rs b/tests/src/lib.rs new file mode 100644 index 0000000..d789500 --- /dev/null +++ b/tests/src/lib.rs @@ -0,0 +1 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause diff --git a/tests/tests/oxerun_smoke_test.rs b/tests/tests/oxerun_smoke_test.rs new file mode 100644 index 0000000..9aa05c3 --- /dev/null +++ b/tests/tests/oxerun_smoke_test.rs @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause + +use std::{ + io::BufRead, + path::Path, + process::{Command, Stdio}, + sync::{Arc, Mutex}, + thread::sleep, + time::{Duration, Instant}, +}; + +#[test] +fn test_run_aarch64_smoke_test_in_qemu() { + let repo_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../oxerun"); + let cargo_bin_path = Path::new(env!("CARGO")); + //cargo build --target aarch64-xen-hvm.json -Zbuild-std=core + // -Zbuild-std-features=compiler-builtins-mem --release + + dbg!(Command::new(&cargo_bin_path) + .args([ + "build", + "--target", + "./aarch64-xen-hvm.json", + "-Zbuild-std=core", + "-Zbuild-std-features=compiler-builtins-mem", + "--release" + ]) + .current_dir(&repo_path) + .stdin(Stdio::null()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .output() + .unwrap()); + + // aarch64-linux-gnu-objcopy target/aarch64-xen-hvm/release/oxerun -O binary + // target/aarch64-xen-hvm/release/oxerun.bin + dbg!(Command::new("aarch64-linux-gnu-objcopy") + .args([ + "./target/aarch64-xen-hvm/release/oxerun", + "-O", + "binary", + "./target/aarch64-xen-hvm/release/oxerun.bin" + ]) + .current_dir(&repo_path) + .stdin(Stdio::null()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .output() + .unwrap()); + + // podman build . | tail -n 1 + let output = dbg!(Command::new("podman") + .args(["build", "."]) + .current_dir(&repo_path) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .output() + .unwrap()); + let id = dbg!(output.stdout.lines().last().unwrap().unwrap()); + + // podman run $img + let mut child = dbg!(Command::new("podman") + .args(["run", &id]) + .current_dir(&repo_path) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap()); + // wait 30 secs max + let start = Instant::now(); + while Instant::now() - start <= Duration::from_secs(30) { + if child.try_wait().is_ok() { + let output = child.wait_with_output().unwrap(); + eprintln!("output:\n{:?}", &output); + eprintln!("{}", String::from_utf8_lossy(&output.stdout)); + return; + } + sleep(Duration::from_millis(250)); + } + if child.try_wait().is_err() { + if let Err(err) = child.kill() { + eprintln!("Could not wait for podmun run: {}", err); + } + let output = child.wait_with_output().unwrap(); + eprintln!("output:\n{:?}", &output); + eprintln!("{}", String::from_utf8_lossy(&output.stdout)); + } +}