Skip to content

Add containerized make test and make test-rpm targets (Fedora + CentOS Stream) #199

Description

@miabbott

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions