From c990f1bdaaf61594d5c439c98444045113370925 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 18 Nov 2025 07:20:58 +0100 Subject: [PATCH] tests: enable `cargo test --workspace` + `#[cfg(devcli_testenv)]` TL;DR: Massive quality of life improvement for devs Cloud Hypervisor uses the Cargo test framework for multiple tests: - normal unit tests - unit tests requiring special environment (the Tap device tests) - integration tests requiring a special environment This prevented the execution of `cargo test --workspace`, which results in a very poor developer experience. Although `./scripts/run_unit_tests.sh` exists, there are valid reasons why devs cannot or even don't want to use it. By adding a new `chv_testenv` rustc config, we can conditionally only activate tests when the `./scripts/` magic runs them. This improves the general developer experience by a lot. Signed-off-by: Philipp Schuster On-behalf-of: SAP philipp.schuster@sap.com --- Cargo.toml | 4 ++++ net_util/src/tap.rs | 1 + scripts/dev_cli.sh | 3 +++ scripts/run_integration_tests_aarch64.sh | 2 ++ scripts/run_integration_tests_live_migration.sh | 3 +++ scripts/run_integration_tests_rate_limiter.sh | 3 +++ scripts/run_integration_tests_vfio.sh | 3 +++ scripts/run_integration_tests_windows_aarch64.sh | 2 ++ scripts/run_integration_tests_windows_x86_64.sh | 2 ++ scripts/run_integration_tests_x86_64.sh | 7 +++---- tests/integration.rs | 1 + 11 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 842a39d88..fa15483fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -162,3 +162,7 @@ zerocopy = { version = "0.8.27", default-features = false } # https://rust-lang.github.io/rust-clippy/master/index.html assertions_on_result_states = "deny" undocumented_unsafe_blocks = "deny" + +[workspace.lints.rust] +# `level = warn` is irrelevant here but mandatory for rustc/cargo +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(devcli_testenv)'] } diff --git a/net_util/src/tap.rs b/net_util/src/tap.rs index 2916e66cf..45d6a77de 100644 --- a/net_util/src/tap.rs +++ b/net_util/src/tap.rs @@ -549,6 +549,7 @@ impl AsRawFd for Tap { } #[cfg(test)] +#[cfg(devcli_testenv)] // we need special permissions in the ENV to create Tap devices mod tests { use std::net::Ipv4Addr; use std::sync::{LazyLock, Mutex, mpsc}; diff --git a/scripts/dev_cli.sh b/scripts/dev_cli.sh index ee95b99b3..d055ed743 100755 --- a/scripts/dev_cli.sh +++ b/scripts/dev_cli.sh @@ -47,6 +47,9 @@ CARGO_GIT_REGISTRY_DIR="${CLH_BUILD_DIR}/cargo_git_registry" # Full path to the cargo target dir on the host. CARGO_TARGET_DIR="${CLH_BUILD_DIR}/cargo_target" +# Let tests know that the special environment is set up. +RUSTFLAGS="${RUSTFLAGS} --cfg devcli_testenv" + # Send a decorated message to stdout, followed by a new line # say() { diff --git a/scripts/run_integration_tests_aarch64.sh b/scripts/run_integration_tests_aarch64.sh index af6b4773c..bd1e3954d 100755 --- a/scripts/run_integration_tests_aarch64.sh +++ b/scripts/run_integration_tests_aarch64.sh @@ -191,7 +191,9 @@ if [ $RES -ne 0 ]; then exit 1 fi +# Common configuration for every test run export RUST_BACKTRACE=1 +export RUSTFLAGS="$RUSTFLAGS" cargo build --features mshv --all --release --target "$BUILD_TARGET" diff --git a/scripts/run_integration_tests_live_migration.sh b/scripts/run_integration_tests_live_migration.sh index 38ddd9e38..9d4af8453 100755 --- a/scripts/run_integration_tests_live_migration.sh +++ b/scripts/run_integration_tests_live_migration.sh @@ -83,7 +83,10 @@ PAGE_NUM=$((12288 * 1024 / HUGEPAGESIZE)) echo "$PAGE_NUM" | sudo tee /proc/sys/vm/nr_hugepages sudo chmod a+rwX /dev/hugepages +# Common configuration for every test run export RUST_BACKTRACE=1 +export RUSTFLAGS="$RUSTFLAGS" + time cargo nextest run $test_features --retries 3 --no-fail-fast --test-threads=$(($(nproc) / 4)) "live_migration_parallel::$test_filter" -- ${test_binary_args[*]} RES=$? diff --git a/scripts/run_integration_tests_rate_limiter.sh b/scripts/run_integration_tests_rate_limiter.sh index 1ae897594..9582ddcb2 100755 --- a/scripts/run_integration_tests_rate_limiter.sh +++ b/scripts/run_integration_tests_rate_limiter.sh @@ -55,7 +55,10 @@ fi cargo build --features mshv --all --release --target "$BUILD_TARGET" +# Common configuration for every test run export RUST_BACKTRACE=1 +export RUSTFLAGS="$RUSTFLAGS" + time cargo nextest run $test_features --test-threads=1 "rate_limiter::$test_filter" -- ${test_binary_args[*]} RES=$? diff --git a/scripts/run_integration_tests_vfio.sh b/scripts/run_integration_tests_vfio.sh index 1f36f9580..a88f92aad 100755 --- a/scripts/run_integration_tests_vfio.sh +++ b/scripts/run_integration_tests_vfio.sh @@ -26,7 +26,10 @@ fi cargo build --features mshv --all --release --target "$BUILD_TARGET" +# Common configuration for every test run export RUST_BACKTRACE=1 +export RUSTFLAGS="$RUSTFLAGS" + time cargo nextest run --test-threads=1 "vfio::test_nvidia" -- ${test_binary_args[*]} RES=$? diff --git a/scripts/run_integration_tests_windows_aarch64.sh b/scripts/run_integration_tests_windows_aarch64.sh index a4dcda7a6..7112609e6 100755 --- a/scripts/run_integration_tests_windows_aarch64.sh +++ b/scripts/run_integration_tests_windows_aarch64.sh @@ -36,7 +36,9 @@ dmsetup mknodes dmsetup create windows-snapshot-base --table "0 $img_blk_size snapshot-origin /dev/mapper/windows-base" dmsetup mknodes +# Common configuration for every test run export RUST_BACKTRACE=1 +export RUSTFLAGS="$RUSTFLAGS" cargo build --all --release --target "$BUILD_TARGET" diff --git a/scripts/run_integration_tests_windows_x86_64.sh b/scripts/run_integration_tests_windows_x86_64.sh index 970803829..c95e51305 100755 --- a/scripts/run_integration_tests_windows_x86_64.sh +++ b/scripts/run_integration_tests_windows_x86_64.sh @@ -41,7 +41,9 @@ dmsetup mknodes cargo build --features mshv --all --release --target "$BUILD_TARGET" +# Common configuration for every test run export RUST_BACKTRACE=1 +export RUSTFLAGS="$RUSTFLAGS" # Only run with 1 thread to avoid tests interfering with one another because # Windows has a static IP configured diff --git a/scripts/run_integration_tests_x86_64.sh b/scripts/run_integration_tests_x86_64.sh index 952f7e8cd..6f89cf865 100755 --- a/scripts/run_integration_tests_x86_64.sh +++ b/scripts/run_integration_tests_x86_64.sh @@ -177,14 +177,16 @@ ulimit -l unlimited # Set number of open descriptors high enough for VFIO tests to run ulimit -n 4096 +# Common configuration for every test run export RUST_BACKTRACE=1 +export RUSTFLAGS="$RUSTFLAGS" + time cargo nextest run $test_features --retries 3 --no-fail-fast --test-threads=$(($(nproc) / 4)) "common_parallel::$test_filter" -- ${test_binary_args[*]} RES=$? # Run some tests in sequence since the result could be affected by other tests # running in parallel. if [ $RES -eq 0 ]; then - export RUST_BACKTRACE=1 cargo nextest run $test_features --retries 3 --no-fail-fast --test-threads=1 "common_sequential::$test_filter" -- ${test_binary_args[*]} RES=$? fi @@ -192,7 +194,6 @@ fi # Run tests on dbus_api if [ $RES -eq 0 ]; then cargo build --features "mshv,dbus_api" --all --release --target "$BUILD_TARGET" - export RUST_BACKTRACE=1 # integration tests now do not reply on build feature "dbus_api" time cargo nextest run $test_features --retries 3 --no-fail-fast --test-threads=$(($(nproc) / 4)) "dbus_api::$test_filter" -- ${test_binary_args[*]} RES=$? @@ -201,14 +202,12 @@ 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 nextest run $test_features --no-tests=warn --retries 3 --no-fail-fast --test-threads=$(($(nproc) / 4)) "fw_cfg::$test_filter" -- ${test_binary_args[*]} RES=$? fi if [ $RES -eq 0 ]; then cargo build --features "mshv,ivshmem" --all --release --target "$BUILD_TARGET" - export RUST_BACKTRACE=1 time cargo nextest run $test_features --retries 3 --no-fail-fast --test-threads=$(($(nproc) / 4)) "ivshmem::$test_filter" -- ${test_binary_args[*]} RES=$? fi diff --git a/tests/integration.rs b/tests/integration.rs index 14ace3850..72d6aed56 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 // +#![cfg(devcli_testenv)] #![allow(clippy::undocumented_unsafe_blocks)] // When enabling the `mshv` feature, we skip quite some tests and // hence have known dead-code. This annotation silences dead-code