From 5d478c534ed38168cf7cc83485ee05e5c00d5e24 Mon Sep 17 00:00:00 2001 From: Alex Orozco Date: Thu, 12 Jun 2025 20:33:03 +0000 Subject: [PATCH] tests: Add fw_cfg device integration test This test verifies that we can see custom items added to the fw_cfg device from inside the guest Signed-off-by: Alex Orozco --- .github/workflows/build.yaml | 3 ++ .github/workflows/quality.yaml | 7 +++- scripts/run_integration_tests_aarch64.sh | 8 ++++ scripts/run_integration_tests_x86_64.sh | 8 ++++ tests/integration.rs | 52 ++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 297b2e153..5c3240664 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -52,6 +52,9 @@ jobs: - name: Build (default features + pvmemcontrol) run: cargo rustc --locked --bin cloud-hypervisor --features "pvmemcontrol" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states + - name: Build (default features + fw_cfg) + run: cargo rustc --locked --bin cloud-hypervisor --features "fw_cfg" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states + - name: Build (mshv) run: cargo rustc --locked --bin cloud-hypervisor --no-default-features --features "mshv" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index b4cddb3ce..576acaffa 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -111,7 +111,12 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} args: --locked --all --all-targets --tests --examples --features "tracing" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states - + - name: Clippy (default features + fw_cfg) + uses: actions-rs/cargo@v1 + with: + use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }} + command: clippy + args: --target=${{ matrix.target }} --locked --all --all-targets --tests --examples --features "fw_cfg" -- -D warnings -D clippy::undocumented_unsafe_blocks -W clippy::assertions_on_result_states - name: Clippy (sev_snp) if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }} uses: houseabsolute/actions-rust-cross@v1 diff --git a/scripts/run_integration_tests_aarch64.sh b/scripts/run_integration_tests_aarch64.sh index 0daa672e8..262faff9a 100755 --- a/scripts/run_integration_tests_aarch64.sh +++ b/scripts/run_integration_tests_aarch64.sh @@ -250,4 +250,12 @@ if [ $RES -eq 0 ]; then RES=$? fi +# Run tests on fw_cfg +if [ $RES -eq 0 ]; then + cargo build --features "fw_cfg" --all --release --target "$BUILD_TARGET" + export RUST_BACKTRACE=1 + time cargo test "fw_cfg::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]} + RES=$? +fi + exit $RES diff --git a/scripts/run_integration_tests_x86_64.sh b/scripts/run_integration_tests_x86_64.sh index 4fec7d04c..4f4491aa7 100755 --- a/scripts/run_integration_tests_x86_64.sh +++ b/scripts/run_integration_tests_x86_64.sh @@ -198,4 +198,12 @@ if [ $RES -eq 0 ]; then RES=$? fi +# Run tests on fw_cfg +if [ $RES -eq 0 ]; then + cargo build --features "mshv,fw_cfg" --all --release --target "$BUILD_TARGET" + export RUST_BACKTRACE=1 + time cargo test "fw_cfg::$test_filter" --target "$BUILD_TARGET" -- ${test_binary_args[*]} + RES=$? +fi + exit $RES diff --git a/tests/integration.rs b/tests/integration.rs index d754ccff8..dc19b7aee 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -11069,3 +11069,55 @@ mod rate_limiter { _test_rate_limiter_group_block(false, 2, 2); } } + +#[cfg(not(target_arch = "riscv64"))] +mod fw_cfg { + use crate::*; + + #[test] + fn test_fw_cfg() { + let jammy = UbuntuDiskConfig::new(JAMMY_IMAGE_NAME.to_string()); + let guest = Guest::new(Box::new(jammy)); + let mut cmd = GuestCommand::new(&guest); + + let kernel_path = direct_kernel_boot_path(); + let cmd_line = DIRECT_KERNEL_BOOT_CMDLINE; + + let test_file = guest.tmp_dir.as_path().join("test-file"); + std::fs::write(&test_file, "test-file-content").unwrap(); + + cmd.args(["--cpus", "boot=4"]) + .args(["--memory", "size=512M"]) + .args(["--kernel", kernel_path.to_str().unwrap()]) + .args(["--cmdline", cmd_line]) + .default_disks() + .default_net() + .args([ + "--fw-cfg-config", + &format!( + "initramfs=off,items=[name=opt/org.test/test-file,file={}]", + test_file.to_str().unwrap() + ), + ]) + .capture_output(); + + let mut child = cmd.spawn().unwrap(); + + let r = std::panic::catch_unwind(|| { + guest.wait_vm_boot(None).unwrap(); + // Wait a while for guest + thread::sleep(std::time::Duration::new(3, 0)); + let result = guest + .ssh_command( + "sudo cat /sys/firmware/qemu_fw_cfg/by_name/opt/org.test/test-file/raw", + ) + .unwrap(); + assert_eq!(result, "test-file-content"); + }); + + kill_child(&mut child); + let output = child.wait_with_output().unwrap(); + + handle_child_output(r, &output); + } +}