ci: Add virtio-villain test suite job

Add a GitHub Actions job that runs the virtio-villain suite against
cloud-hypervisor, giving continuous coverage of how the virtio device
model responds to guest input that violates the driver side rules of
the virtio specification. The suite drives the device model from the
guest side with out of spec virtqueue input, malformed descriptor
chains, transport register abuse, and device specific requests, then
checks that each violation is handled without crashing the device or
leaving it wedged. This makes a class of guest triggered failures a
signal that shows up on every relevant change rather than found by
chance.

The job builds cloud-hypervisor with the kvm feature, clones
virtio-villain at a pinned tag, builds its initramfs, and runs the
tests in short lived VMs, rerunning a wedged batch in isolation so a
failure is attributed to the offending test. Results reach the run
summary page, and the JUnit report plus per test logs upload as an
artifact. The compiled harness, the initramfs, and the fetched guest
kernel are cached under the resolved villain commit, so an unchanged
pin skips the rebuild.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Assisted-by: Claude:Opus-4.8
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-07-11 11:10:27 +02:00
committed by Rob Bradford
parent f9f07b49d2
commit a8738c5897

View File

@@ -846,6 +846,84 @@ jobs:
# - name: Run rate-limiter integration tests
# timeout-minutes: 20
# run: scripts/dev_cli.sh tests --integration-rate-limiter
virtio-villain:
name: virtio-villain
needs: [preflight, dco, quality, build]
if: needs.preflight.outputs.full == 'true'
timeout-minutes: 60
runs-on: ubuntu-latest
env:
VILLAIN_REPO: https://github.com/weltling/virtio-villain.git
VILLAIN_REF: v0.5.0
steps:
- name: Code checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Verify KVM is available
run: |
set -eufo pipefail
test -e /dev/kvm || { echo "::error::/dev/kvm missing on runner"; exit 1; }
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: |
set -eufo pipefail
sudo apt-get update
sudo apt-get install -y musl-tools cpio gzip python3
sudo apt-get install -y virtiofsd || true
- name: Build cloud-hypervisor (kvm)
run: cargo build --locked --release --bin cloud-hypervisor --no-default-features --features kvm
- name: Clone virtio-villain
id: villain-src
run: |
set -eufo pipefail
git clone "$VILLAIN_REPO" virtio-villain
git -C virtio-villain checkout "$VILLAIN_REF"
echo "sha=$(git -C virtio-villain rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Cache virtio-villain build
id: villain-cache
uses: actions/cache@v4
with:
path: virtio-villain/target
key: virtio-villain-${{ runner.os }}-${{ runner.arch }}-${{ steps.villain-src.outputs.sha }}
- name: Build virtio-villain initramfs
if: steps.villain-cache.outputs.cache-hit != 'true'
run: make -C virtio-villain -j"$(nproc)" initramfs
- name: Run virtio-villain suite
working-directory: virtio-villain
run: |
set -eufo pipefail
mkdir -p villain-logs
sudo ./run \
--vmm "${GITHUB_WORKSPACE}/target/release/cloud-hypervisor" \
--blk-queues 2 --net-queues 2 --cpus 2 --memory 256M \
--order=fast \
--jobs 4 --batch 10 --timeout 45 --log-dir villain-logs \
--format junit --output villain-logs/results.xml \
| tee villain-logs/run.out
- name: Publish results to run summary
if: always()
working-directory: virtio-villain
run: |
set -eufo pipefail
{
echo '## virtio-villain'
echo '```'
if [ -f villain-logs/run.out ]; then
sed -n '/tests passed/,$p' villain-logs/run.out
else
echo 'no results (suite did not produce output)'
fi
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload virtio-villain logs
if: always()
uses: actions/upload-artifact@v7
with:
name: virtio-villain-logs
path: virtio-villain/villain-logs
if-no-files-found: ignore
# The single required-status check. Branch protection requires this one job.
all-green:
name: all-green