Skip to content

Commit cfcb575

Browse files
committed
Rework integration testing
The nextest config (.config/nextest.toml) was previously dead code — tests were run via the libtest-mimic binary directly. Switch the Justfile targets and CI workflow to prefer nextest when available, so the parallelism controls (threads-required = 2 for privileged VM tests) actually take effect and prevent OOM kills on 16 GB CI runners. Also fix the nextest filter syntax: ~^foo never matches because nextest's ~ operator treats ^ as a literal character. Use /regex/ syntax instead. Add default-members to the workspace Cargo.toml so that bare `cargo test` (and `cargo build`, `cargo clippy`, etc.) skip the integration-tests crate, which requires a built cfsctl binary and (for privileged tests) a VM. This matches the pattern used by bcvk. The integration-tests crate keeps both [[bin]] and [[test]] targets pointing at src/main.rs so that nextest discovers the libtest-mimic tests when explicitly targeted via `just test-integration`. Assisted-by: OpenCode (Claude Opus 4) Signed-off-by: Colin Walters <walters@verbum.org>
1 parent b7f66aa commit cfcb575

5 files changed

Lines changed: 68 additions & 9 deletions

File tree

.config/nextest.toml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ failure-output = "immediate"
1414
success-output = "never"
1515
status-level = "pass"
1616

17+
# Tests that pull OCI images need more time (especially on cold CI runners)
18+
[[profile.default.overrides]]
19+
filter = 'test(/digest_stability|oci_pull/)'
20+
slow-timeout = { period = "300s", terminate-after = 2 }
21+
1722
# Profile for integration tests — run with limited parallelism due to QEMU/KVM resources
1823
[profile.integration]
1924
test-threads = 2
@@ -30,7 +35,12 @@ path = "junit.xml"
3035
store-success-output = true
3136
store-failure-output = true
3237

33-
# VM tests boot an ephemeral QEMU instance per test, limit parallelism
38+
# Privileged tests boot an ephemeral QEMU instance per test — limit
39+
# parallelism to avoid OOM kills on 16 GB CI runners.
40+
# Requiring all 2 threads effectively serialises them.
41+
#
42+
# NOTE: use /regex/ syntax, not ~substring — the ~ operator treats ^ $ as
43+
# literal characters, so ~^foo never matches anything.
3444
[[profile.integration.overrides]]
35-
filter = 'test(~^vm_)'
36-
threads-required = 4
45+
filter = 'test(/^privileged_/)'
46+
threads-required = 2

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ jobs:
5151
- uses: actions/checkout@v6
5252
- uses: bootc-dev/actions/bootc-ubuntu-setup@main
5353
- uses: dtolnay/rust-toolchain@stable
54+
- uses: taiki-e/install-action@nextest
5455
- uses: Swatinem/rust-cache@v2
5556
- run: just test-integration
5657

@@ -114,6 +115,7 @@ jobs:
114115
libvirt: true
115116

116117
- uses: dtolnay/rust-toolchain@stable
118+
- uses: taiki-e/install-action@nextest
117119

118120
- uses: Swatinem/rust-cache@v2
119121

Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
[workspace]
22
members = ["crates/*"]
3+
# Exclude integration-tests from default `cargo test` — those require a
4+
# built cfsctl binary and (for privileged tests) a VM. Run them via
5+
# `just test-integration` or `just test-integration-vm` instead.
6+
default-members = [
7+
"crates/cfsctl",
8+
"crates/composefs",
9+
"crates/composefs-boot",
10+
"crates/composefs-fuse",
11+
"crates/composefs-http",
12+
"crates/composefs-ioctls",
13+
"crates/composefs-oci",
14+
"crates/composefs-setup-root",
15+
"crates/cstorage",
16+
"crates/erofs-debug",
17+
"crates/splitfdstream",
18+
]
319
resolver = "2"
420

521
[workspace.package]

Justfile

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,37 @@ cfsctl_features := env("COMPOSEFS_CFSCTL_FEATURES", "pre-6.15")
5858
_test_image := if base_image =~ "debian" { "localhost/composefs-rs-test-debian:latest" } else if base_image =~ "stream9" { "localhost/composefs-rs-test-c9s:latest" } else { "localhost/composefs-rs-test:latest" }
5959

6060
# Run unprivileged integration tests against the cfsctl binary (no root, no VM)
61-
test-integration: build
62-
CFSCTL_PATH=$(pwd)/target/debug/cfsctl cargo run -p integration-tests --bin cfsctl-integration-tests -- --skip privileged_
61+
# Prefers nextest for parallelism control and better UX; falls back to direct harness.
62+
test-integration *ARGS: build
63+
#!/usr/bin/env bash
64+
set -euo pipefail
65+
export CFSCTL_PATH=$(pwd)/target/debug/cfsctl
66+
if command -v cargo-nextest &> /dev/null; then
67+
cargo nextest run -p integration-tests -E 'not test(/^privileged_/)' {{ ARGS }}
68+
else
69+
cargo test -p integration-tests --test cfsctl-integration-tests -- --skip privileged_ {{ ARGS }}
70+
fi
6371
6472
# Build the test container image for VM-based integration tests
6573
_integration-container-build:
6674
podman build --build-arg base_image={{base_image}} --build-arg cfsctl_features={{cfsctl_features}} -t {{_test_image}} .
6775

6876
# Run all integration tests including privileged VM tests (requires podman + libvirt)
69-
test-integration-vm: build _integration-container-build
70-
COMPOSEFS_TEST_IMAGE={{_test_image}} \
71-
CFSCTL_PATH=$(pwd)/target/debug/cfsctl \
72-
cargo run -p integration-tests --bin cfsctl-integration-tests
77+
# Uses nextest with the integration profile for parallelism control of VM tests.
78+
test-integration-vm *ARGS: build _integration-container-build
79+
#!/usr/bin/env bash
80+
set -euo pipefail
81+
export COMPOSEFS_TEST_IMAGE={{_test_image}}
82+
export CFSCTL_PATH=$(pwd)/target/debug/cfsctl
83+
if command -v cargo-nextest &> /dev/null; then
84+
cargo nextest run -P integration -p integration-tests {{ ARGS }}
85+
else
86+
cargo test -p integration-tests --test cfsctl-integration-tests -- {{ ARGS }}
87+
fi
88+
89+
# Install cargo-nextest if not already installed
90+
install-nextest:
91+
@which cargo-nextest > /dev/null 2>&1 || cargo install cargo-nextest --locked
7392

7493
# Run everything: checks + full integration tests including VM
7594
ci: check test-integration-vm

crates/integration-tests/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,29 @@
22
name = "integration-tests"
33
publish = false
44
description = "Integration tests for composefs-rs (not published)"
5+
autobins = false
6+
autotests = false
57

68
edition.workspace = true
79
license.workspace = true
810
repository.workspace = true
911
rust-version.workspace = true
1012
version.workspace = true
1113

14+
# The integration test runner is declared as both [[bin]] (for the container
15+
# image build) and [[test]] (so nextest discovers the libtest-mimic tests).
16+
# The integration-tests crate is excluded from workspace default-members so
17+
# that plain `cargo test` does not run these; use `just test-integration`.
18+
# Cargo warns about the shared source file — this is harmless.
1219
[[bin]]
1320
name = "cfsctl-integration-tests"
1421
path = "src/main.rs"
1522

23+
[[test]]
24+
name = "cfsctl-integration-tests"
25+
path = "src/main.rs"
26+
harness = false
27+
1628
[[bin]]
1729
name = "test-cleanup"
1830
path = "src/cleanup.rs"

0 commit comments

Comments
 (0)