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 <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
Philipp Schuster
2025-11-18 07:20:58 +01:00
committed by Bo Chen
parent e3e9e1c84c
commit c990f1bdaa
11 changed files with 27 additions and 4 deletions

View File

@@ -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)'] }

View File

@@ -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};

View File

@@ -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() {

View File

@@ -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"

View File

@@ -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=$?

View File

@@ -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=$?

View File

@@ -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=$?

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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