Problem
Even once unit tests are sandboxed (see #198), a contributor still needs a Rust toolchain installed to run cargo test, and needs rpmbuild plus Rust packaging macros to build RPMs (make rpm). There's no make test target at all today — the closest is make check, which assumes Rust is already on the host.
The goal stated in #197 is that a contributor should be able to run make test with nothing but a container runtime installed. Since the project already builds and ships for both Fedora and CentOS Stream/RHEL (see the bundled_rust_deps conditional in greenboot-rs.spec, and the CentOS Stream 9 container used by the make-rpm CI job), the containerized test path should cover both, not just Fedora.
Proposed approach
Add two small, purpose-built container images:
Containerfile.test — based on fedora:latest, with the native Fedora Rust toolchain and cargo-rpm-macros packaging path (matching the %bcond bundled_rust_deps 0 branch in the spec).
Containerfile.test.centos — based on quay.io/centos/centos:stream9 (or stream10, open to discussion), using rust-toolset and the bundled/vendored Rust dependency path (matching the %bcond bundled_rust_deps branch and the existing make-rpm CI job, which already builds RPMs this way on CentOS Stream 9).
Both are distinct from .devcontainer/Dockerfile, which is for interactive VS Code development, not CI/test automation.
Add Makefile targets that build these images (lazily, on first use) and run commands inside them with the working tree bind-mounted:
make test — runs cargo test inside the Fedora container
make test-centos — runs cargo test inside the CentOS Stream container
make test-rpm — runs make rpm inside the Fedora container
make test-rpm-centos — runs make rpm inside the CentOS Stream container
make test-container / make test-container-centos — force-rebuild the respective container image
make test-coverage — containerized equivalent of the current sudo-based coverage target
make check should remain as-is: a bare-metal cargo test for contributors who already have Rust installed and want the fastest possible feedback loop without container overhead. All of check, test, and test-centos run the same test suite; they differ only in execution environment.
To avoid recompiling from scratch on every invocation, each container's cargo/target output should be cached across runs using a persistent podman volume rather than being discarded when the container exits. Fedora and CentOS Stream caches should be kept separate to avoid glibc/ABI mismatches.
CI's build_and_test_with_coverage job should be updated to build and use Containerfile.test, and consideration should be given to also running the CentOS Stream variant in CI (or at minimum keeping Containerfile.test.centos validated by the existing make-rpm job path), so local and CI test environments are guaranteed to match.
Host requirements
podman only. (Podman was already the container runtime of choice discussed for this project; docker compatibility is not a goal here.)
Discussion points
- Which CentOS Stream major version should be the default for
Containerfile.test.centos — stream9 (matches current make-rpm CI job) or stream10 (matches newer bootc/RHEL 10 targets used elsewhere in the test matrix)? Should both be supported via a build-arg within that one Containerfile, or does that reintroduce the complexity we're trying to avoid by having separate files per distro family?
- Naming/location of the Containerfiles — top-level vs. a
containers/ subdirectory, given the repo already has a top-level Containerfile used for integration testing and a .devcontainer/Dockerfile.
- Should
make check and make test be merged into one, with test auto-detecting whether Rust is available on the host and falling back to the container otherwise? Or is keeping them as explicit, separate targets clearer for contributors?
- Cache invalidation strategy for the persistent cargo/target volumes when a container image itself is rebuilt (e.g. after a Rust version bump).
Problem
Even once unit tests are sandboxed (see #198), a contributor still needs a Rust toolchain installed to run
cargo test, and needsrpmbuildplus Rust packaging macros to build RPMs (make rpm). There's nomake testtarget at all today — the closest ismake check, which assumes Rust is already on the host.The goal stated in #197 is that a contributor should be able to run
make testwith nothing but a container runtime installed. Since the project already builds and ships for both Fedora and CentOS Stream/RHEL (see thebundled_rust_depsconditional ingreenboot-rs.spec, and the CentOS Stream 9 container used by themake-rpmCI job), the containerized test path should cover both, not just Fedora.Proposed approach
Add two small, purpose-built container images:
Containerfile.test— based onfedora:latest, with the native Fedora Rust toolchain andcargo-rpm-macrospackaging path (matching the%bcond bundled_rust_deps 0branch in the spec).Containerfile.test.centos— based onquay.io/centos/centos:stream9(or stream10, open to discussion), usingrust-toolsetand the bundled/vendored Rust dependency path (matching the%bcond bundled_rust_depsbranch and the existingmake-rpmCI job, which already builds RPMs this way on CentOS Stream 9).Both are distinct from
.devcontainer/Dockerfile, which is for interactive VS Code development, not CI/test automation.Add Makefile targets that build these images (lazily, on first use) and run commands inside them with the working tree bind-mounted:
make test— runscargo testinside the Fedora containermake test-centos— runscargo testinside the CentOS Stream containermake test-rpm— runsmake rpminside the Fedora containermake test-rpm-centos— runsmake rpminside the CentOS Stream containermake test-container/make test-container-centos— force-rebuild the respective container imagemake test-coverage— containerized equivalent of the currentsudo-based coverage targetmake checkshould remain as-is: a bare-metalcargo testfor contributors who already have Rust installed and want the fastest possible feedback loop without container overhead. All ofcheck,test, andtest-centosrun the same test suite; they differ only in execution environment.To avoid recompiling from scratch on every invocation, each container's cargo/target output should be cached across runs using a persistent podman volume rather than being discarded when the container exits. Fedora and CentOS Stream caches should be kept separate to avoid glibc/ABI mismatches.
CI's
build_and_test_with_coveragejob should be updated to build and useContainerfile.test, and consideration should be given to also running the CentOS Stream variant in CI (or at minimum keepingContainerfile.test.centosvalidated by the existingmake-rpmjob path), so local and CI test environments are guaranteed to match.Host requirements
podman only. (Podman was already the container runtime of choice discussed for this project; docker compatibility is not a goal here.)
Discussion points
Containerfile.test.centos— stream9 (matches currentmake-rpmCI job) or stream10 (matches newer bootc/RHEL 10 targets used elsewhere in the test matrix)? Should both be supported via a build-arg within that one Containerfile, or does that reintroduce the complexity we're trying to avoid by having separate files per distro family?containers/subdirectory, given the repo already has a top-levelContainerfileused for integration testing and a.devcontainer/Dockerfile.make checkandmake testbe merged into one, withtestauto-detecting whether Rust is available on the host and falling back to the container otherwise? Or is keeping them as explicit, separate targets clearer for contributors?