From 759fd3b2d27c10d64cd268e356614ed91d84090c Mon Sep 17 00:00:00 2001 From: Reto Gantenbein Date: Sun, 22 Mar 2026 12:16:26 +0100 Subject: [PATCH] openspec: Archive e2e-github-workflow change spec --- .../.openspec.yaml | 0 .../2026-03-22-e2e-github-workflow}/design.md | 0 .../proposal.md | 0 .../specs/e2e-github-workflow/spec.md | 0 .../specs/e2e-multi-distro/spec.md | 0 .../specs/e2e-testing/spec.md | 0 .../2026-03-22-e2e-github-workflow}/tasks.md | 0 openspec/specs/e2e-github-workflow/spec.md | 44 ++++++ openspec/specs/e2e-multi-distro/spec.md | 85 +++++++++++ openspec/specs/e2e-testing/spec.md | 144 ++++++++++++------ 10 files changed, 228 insertions(+), 45 deletions(-) rename openspec/changes/{e2e-github-workflow => archive/2026-03-22-e2e-github-workflow}/.openspec.yaml (100%) rename openspec/changes/{e2e-github-workflow => archive/2026-03-22-e2e-github-workflow}/design.md (100%) rename openspec/changes/{e2e-github-workflow => archive/2026-03-22-e2e-github-workflow}/proposal.md (100%) rename openspec/changes/{e2e-github-workflow => archive/2026-03-22-e2e-github-workflow}/specs/e2e-github-workflow/spec.md (100%) rename openspec/changes/{e2e-github-workflow => archive/2026-03-22-e2e-github-workflow}/specs/e2e-multi-distro/spec.md (100%) rename openspec/changes/{e2e-github-workflow => archive/2026-03-22-e2e-github-workflow}/specs/e2e-testing/spec.md (100%) rename openspec/changes/{e2e-github-workflow => archive/2026-03-22-e2e-github-workflow}/tasks.md (100%) create mode 100644 openspec/specs/e2e-github-workflow/spec.md create mode 100644 openspec/specs/e2e-multi-distro/spec.md diff --git a/openspec/changes/e2e-github-workflow/.openspec.yaml b/openspec/changes/archive/2026-03-22-e2e-github-workflow/.openspec.yaml similarity index 100% rename from openspec/changes/e2e-github-workflow/.openspec.yaml rename to openspec/changes/archive/2026-03-22-e2e-github-workflow/.openspec.yaml diff --git a/openspec/changes/e2e-github-workflow/design.md b/openspec/changes/archive/2026-03-22-e2e-github-workflow/design.md similarity index 100% rename from openspec/changes/e2e-github-workflow/design.md rename to openspec/changes/archive/2026-03-22-e2e-github-workflow/design.md diff --git a/openspec/changes/e2e-github-workflow/proposal.md b/openspec/changes/archive/2026-03-22-e2e-github-workflow/proposal.md similarity index 100% rename from openspec/changes/e2e-github-workflow/proposal.md rename to openspec/changes/archive/2026-03-22-e2e-github-workflow/proposal.md diff --git a/openspec/changes/e2e-github-workflow/specs/e2e-github-workflow/spec.md b/openspec/changes/archive/2026-03-22-e2e-github-workflow/specs/e2e-github-workflow/spec.md similarity index 100% rename from openspec/changes/e2e-github-workflow/specs/e2e-github-workflow/spec.md rename to openspec/changes/archive/2026-03-22-e2e-github-workflow/specs/e2e-github-workflow/spec.md diff --git a/openspec/changes/e2e-github-workflow/specs/e2e-multi-distro/spec.md b/openspec/changes/archive/2026-03-22-e2e-github-workflow/specs/e2e-multi-distro/spec.md similarity index 100% rename from openspec/changes/e2e-github-workflow/specs/e2e-multi-distro/spec.md rename to openspec/changes/archive/2026-03-22-e2e-github-workflow/specs/e2e-multi-distro/spec.md diff --git a/openspec/changes/e2e-github-workflow/specs/e2e-testing/spec.md b/openspec/changes/archive/2026-03-22-e2e-github-workflow/specs/e2e-testing/spec.md similarity index 100% rename from openspec/changes/e2e-github-workflow/specs/e2e-testing/spec.md rename to openspec/changes/archive/2026-03-22-e2e-github-workflow/specs/e2e-testing/spec.md diff --git a/openspec/changes/e2e-github-workflow/tasks.md b/openspec/changes/archive/2026-03-22-e2e-github-workflow/tasks.md similarity index 100% rename from openspec/changes/e2e-github-workflow/tasks.md rename to openspec/changes/archive/2026-03-22-e2e-github-workflow/tasks.md diff --git a/openspec/specs/e2e-github-workflow/spec.md b/openspec/specs/e2e-github-workflow/spec.md new file mode 100644 index 0000000..90220f7 --- /dev/null +++ b/openspec/specs/e2e-github-workflow/spec.md @@ -0,0 +1,44 @@ +## Requirements + +### Requirement: GitHub Actions e2e workflow with workflow_dispatch trigger +The project SHALL provide a GitHub Actions workflow at `.github/workflows/e2e.yaml` that runs e2e tests. The workflow SHALL be triggered only via `workflow_dispatch` (manual trigger). The workflow SHALL NOT run automatically on push or pull request events. + +#### Scenario: Workflow is triggered manually +- **WHEN** a user triggers the e2e workflow via the GitHub Actions UI or API +- **THEN** the workflow starts and runs the e2e test matrix + +#### Scenario: Workflow does not run on push +- **WHEN** code is pushed to any branch +- **THEN** the e2e workflow is NOT triggered + +### Requirement: Matrix strategy with one job per distro/release tuple +The workflow SHALL use a GitHub Actions matrix strategy with one job per distro/release tuple. Each matrix entry SHALL define a display name, the Go test function name to run, and the release version. Each job SHALL appear as a separate entry in the GitHub Actions UI for clear failure isolation. + +#### Scenario: Matrix produces separate jobs +- **WHEN** the e2e workflow is triggered +- **THEN** GitHub Actions creates one job per matrix entry, each visible as a separate row in the workflow run UI + +#### Scenario: Each job runs exactly one distro test +- **WHEN** a matrix job executes +- **THEN** it runs only the Go test function specified by the matrix entry (e.g., `TestFedora`) with the release specified by `E2E_RELEASE` + +### Requirement: 5-minute timeout per matrix job +Each matrix job SHALL have a `timeout-minutes` of 5. + +#### Scenario: Job exceeds timeout +- **WHEN** a matrix job runs longer than 5 minutes +- **THEN** the job is cancelled by GitHub Actions + +### Requirement: Matrix includes all supported distro/release tuples +The workflow matrix SHALL include the following distro/release tuples: Fedora 43, CentOS Stream 10, AlmaLinux 10, Rocky Linux 10, Debian trixie, Ubuntu noble, Arch Linux latest. + +#### Scenario: All distros are represented in the matrix +- **WHEN** the e2e workflow is triggered +- **THEN** jobs are created for Fedora 43, CentOS Stream 10, AlmaLinux 10, Rocky Linux 10, Debian trixie, Ubuntu noble, and Arch Linux latest + +### Requirement: Workflow job steps +Each matrix job SHALL checkout the repository, set up Go, and run the e2e test for the specific distro using `go test -tags e2e -run ./test/e2e/` with the `E2E_RELEASE` environment variable set from the matrix. + +#### Scenario: Job executes test with correct parameters +- **WHEN** a matrix job for Fedora 43 runs +- **THEN** it executes `go test -tags e2e -run TestFedora ./test/e2e/` with `E2E_RELEASE=43` diff --git a/openspec/specs/e2e-multi-distro/spec.md b/openspec/specs/e2e-multi-distro/spec.md new file mode 100644 index 0000000..b2d87db --- /dev/null +++ b/openspec/specs/e2e-multi-distro/spec.md @@ -0,0 +1,85 @@ +## Requirements + +### Requirement: CentOS Stream e2e test +The test suite SHALL include a CentOS Stream test function `TestCentOSStream` using a `quay.io/centos/centos:stream10` container (or the release specified by `E2E_RELEASE`). The test SHALL configure dnf with a base repo pointing at the pkgproxy `centos-stream` repository, an EPEL repo pointing at the pkgproxy `epel` repository, and a COPR repo pointing at `ganto/jo` using the `epel-$releasever-$basearch` pattern. GPG verification SHALL be enabled for base and EPEL repos, disabled for COPR. + +#### Scenario: CentOS Stream base package install succeeds +- **WHEN** the CentOS Stream container runs `dnf install -y tree` through pkgproxy +- **THEN** the command exits successfully and cached `.rpm` files exist under the `centos-stream/` cache subdirectory + +#### Scenario: CentOS Stream EPEL metadata is accessible +- **WHEN** the CentOS Stream container runs `dnf makecache` with the EPEL repo configured +- **THEN** the command exits successfully (no cache assertion for EPEL) + +#### Scenario: CentOS Stream COPR package install succeeds +- **WHEN** the CentOS Stream container runs `dnf install -y jo` from the COPR repository through pkgproxy +- **THEN** the command exits successfully and cached `.rpm` files exist under the `copr/` cache subdirectory + +### Requirement: AlmaLinux e2e test +The test suite SHALL include an AlmaLinux test function `TestAlmaLinux` using a `docker.io/library/almalinux:10` container (or the release specified by `E2E_RELEASE`). The test SHALL configure dnf with a base repo pointing at the pkgproxy `almalinux` repository, an EPEL repo, and a COPR repo using the `epel-$releasever-$basearch` pattern. + +#### Scenario: AlmaLinux base package install succeeds +- **WHEN** the AlmaLinux container runs `dnf install -y tree` through pkgproxy +- **THEN** the command exits successfully and cached `.rpm` files exist under the `almalinux/` cache subdirectory + +#### Scenario: AlmaLinux EPEL metadata is accessible +- **WHEN** the AlmaLinux container runs `dnf makecache` with the EPEL repo configured +- **THEN** the command exits successfully + +#### Scenario: AlmaLinux COPR package install succeeds +- **WHEN** the AlmaLinux container runs `dnf install -y jo` from the COPR repository through pkgproxy +- **THEN** the command exits successfully and cached `.rpm` files exist under the `copr/` cache subdirectory + +### Requirement: Rocky Linux e2e test +The test suite SHALL include a Rocky Linux test function `TestRockyLinux` using a `docker.io/library/rockylinux:10` container (or the release specified by `E2E_RELEASE`). The test SHALL configure dnf with a base repo pointing at the pkgproxy `rockylinux` repository, an EPEL repo, and a COPR repo using the `epel-$releasever-$basearch` pattern. + +#### Scenario: Rocky Linux base package install succeeds +- **WHEN** the Rocky Linux container runs `dnf install -y tree` through pkgproxy +- **THEN** the command exits successfully and cached `.rpm` files exist under the `rockylinux/` cache subdirectory + +#### Scenario: Rocky Linux EPEL metadata is accessible +- **WHEN** the Rocky Linux container runs `dnf makecache` with the EPEL repo configured +- **THEN** the command exits successfully + +#### Scenario: Rocky Linux COPR package install succeeds +- **WHEN** the Rocky Linux container runs `dnf install -y jo` from the COPR repository through pkgproxy +- **THEN** the command exits successfully and cached `.rpm` files exist under the `copr/` cache subdirectory + +### Requirement: Ubuntu e2e test +The test suite SHALL include an Ubuntu test function `TestUbuntu` using a `docker.io/library/ubuntu:noble` container (or the release specified by `E2E_RELEASE`). The test SHALL configure apt with sources pointing at the pkgproxy `ubuntu` and `ubuntu-security` repositories. The `sources.list` SHALL be generated by the Go test and mounted into the container. + +#### Scenario: Ubuntu metadata refresh succeeds +- **WHEN** the Ubuntu container runs `apt-get update` through pkgproxy +- **THEN** the command exits successfully + +#### Scenario: Ubuntu package install succeeds +- **WHEN** the Ubuntu container runs `apt-get install -y tree` through pkgproxy +- **THEN** the command exits successfully and cached `.deb` files exist under the `ubuntu/` cache subdirectory + +### Requirement: ubuntu-security repository in pkgproxy config +The pkgproxy configuration (`configs/pkgproxy.yaml`) SHALL include a `ubuntu-security` repository with `.deb` suffix and mirrors including `https://security.ubuntu.com/ubuntu/`. + +#### Scenario: ubuntu-security repository is configured +- **WHEN** pkgproxy loads its configuration +- **THEN** the `ubuntu-security` repository is available with at least one upstream mirror + +### Requirement: Fully qualified container image names +All e2e tests SHALL use fully qualified container image names including the registry (e.g., `docker.io/library/fedora:43`, `quay.io/centos/centos:stream10`). Tests SHALL NOT depend on container runtime defaults for registry resolution. + +#### Scenario: Images use fully qualified names +- **WHEN** any e2e test starts a container +- **THEN** the image reference includes the full registry path + +### Requirement: Architecture-independent repo configuration +All e2e test repo configurations SHALL use `$basearch` for architecture and `$releasever` for release version instead of hardcoded values. This SHALL allow the tests to run on both x86_64 and arm64 hosts. + +#### Scenario: Repo files use variables not hardcoded values +- **WHEN** the Go test generates a `.repo` file or `sources.list` +- **THEN** the file uses `$basearch` and `$releasever` variables where supported by the package manager + +### Requirement: COPR for non-Fedora DNF distros uses EPEL pattern +COPR repository configuration for non-Fedora DNF-based distros (CentOS Stream, AlmaLinux, Rocky Linux) SHALL use the URL pattern `/copr/ganto/jo/epel-$releasever-$basearch/`. Fedora SHALL continue using `/copr/ganto/jo/fedora-$releasever-$basearch/`. + +#### Scenario: Non-Fedora COPR uses epel pattern +- **WHEN** the Go test generates a COPR repo file for AlmaLinux +- **THEN** the baseurl uses the pattern `http:///copr/ganto/jo/epel-$releasever-$basearch/` diff --git a/openspec/specs/e2e-testing/spec.md b/openspec/specs/e2e-testing/spec.md index 83f8156..277b2a8 100644 --- a/openspec/specs/e2e-testing/spec.md +++ b/openspec/specs/e2e-testing/spec.md @@ -1,7 +1,7 @@ ## Requirements ### Requirement: E2e test framework with container runtime -The project SHALL provide end-to-end tests in `test/e2e/` that start a real pkgproxy process, run Linux distribution containers via a container runtime (podman or docker), and exercise real package managers against real upstream mirrors through the proxy. Tests SHALL be gated behind a `//go:build e2e` build tag and a `make e2e` Makefile target. +The project SHALL provide end-to-end tests in `test/e2e/` that start a real pkgproxy process, run Linux distribution containers via a container runtime (podman or docker), and exercise real package managers against real upstream mirrors through the proxy. Tests SHALL be gated behind a `//go:build e2e` build tag and a `make e2e` Makefile target. Each distribution SHALL have its own top-level test function (e.g., `TestFedora`, `TestDebian`) instead of subtests under a single `TestE2E` function. #### Scenario: E2e tests do not run during standard test suite - **WHEN** a developer runs `make test` or `make ci-check` @@ -9,7 +9,15 @@ The project SHALL provide end-to-end tests in `test/e2e/` that start a real pkgp #### Scenario: E2e tests run via make target - **WHEN** a developer runs `make e2e` -- **THEN** the e2e test suite is executed with the `e2e` build tag +- **THEN** all e2e test functions are executed with the `e2e` build tag and default release versions + +#### Scenario: E2e tests run for a specific distro +- **WHEN** a developer runs `make e2e DISTRO=fedora` +- **THEN** only `TestFedora` is executed with the default release version + +#### Scenario: E2e tests run for a specific distro and release +- **WHEN** a developer runs `make e2e DISTRO=fedora RELEASE=42` +- **THEN** only `TestFedora` is executed with `E2E_RELEASE=42` ### Requirement: Container runtime auto-detection with override The e2e test SHALL auto-detect the available container runtime by checking for `podman` first, then `docker`. The runtime SHALL be overridable via the `CONTAINER_RUNTIME` environment variable. The host gateway hostname SHALL be set automatically based on the detected runtime: `host.containers.internal` for podman, `host.docker.internal` for docker. @@ -30,26 +38,56 @@ The e2e test SHALL auto-detect the available container runtime by checking for ` - **WHEN** neither `podman` nor `docker` is found and `CONTAINER_RUNTIME` is not set - **THEN** the test is skipped with a descriptive message -### Requirement: Pkgproxy starts as a host-side subprocess -The e2e test SHALL build and start pkgproxy as a subprocess listening on `0.0.0.0` with a dynamically allocated free port, using the production `configs/pkgproxy.yaml`. The process SHALL be terminated after all subtests complete. +### Requirement: Pkgproxy binary built once via TestMain +The e2e test package SHALL use a `TestMain` function to build the pkgproxy binary once into a shared temporary directory before any test functions run. The binary path SHALL be stored in a package-level variable. Each top-level test function SHALL reuse this pre-built binary when starting its own pkgproxy process. The temporary directory SHALL be cleaned up after all tests complete. + +#### Scenario: Binary is built once for all tests +- **WHEN** `go test -tags e2e ./test/e2e/` runs multiple test functions +- **THEN** the pkgproxy binary is built exactly once via `TestMain` + +#### Scenario: Each test function starts its own pkgproxy process +- **WHEN** `TestFedora` and `TestDebian` both run +- **THEN** each starts a separate pkgproxy process from the shared binary, with its own port and cache directory -#### Scenario: Pkgproxy binds to a free port -- **WHEN** the e2e test suite starts -- **THEN** pkgproxy is built, started on `0.0.0.0:`, and reachable from podman containers via `host.containers.internal:` (podman) or `host.docker.internal:` (docker) +### Requirement: E2E_RELEASE environment variable for release parameterization +Each top-level e2e test function SHALL read the `E2E_RELEASE` environment variable to determine the distribution release version. If `E2E_RELEASE` is not set, the test SHALL use a sensible default release (e.g., `43` for Fedora, `trixie` for Debian, `noble` for Ubuntu, `10` for CentOS Stream/AlmaLinux/Rocky Linux). + +#### Scenario: Default release is used when E2E_RELEASE is unset +- **WHEN** `TestFedora` runs without `E2E_RELEASE` set +- **THEN** the test uses the default release `43` + +#### Scenario: E2E_RELEASE overrides the default +- **WHEN** `TestFedora` runs with `E2E_RELEASE=42` +- **THEN** the test uses release `42` for the container image and repo configuration + +### Requirement: Per-distro-family shell scripts +The e2e tests SHALL use per-distro-family shell scripts (`test-dnf.sh`, `test-pacman.sh`) located in `test/e2e/` that are mounted into containers. The `test-apt.sh` script SHALL have its `sources.list` generation removed (handled by the Go test instead), but SHALL retain cleanup of `sources.list.d/` entries, setting `DEBIAN_FRONTEND=noninteractive`, and running `apt-get update` and `apt-get install`. DNF repo file generation SHALL remain in the Go test. -#### Scenario: Pkgproxy is stopped after tests -- **WHEN** all e2e subtests have completed -- **THEN** the pkgproxy subprocess is terminated and the cache directory is cleaned up +#### Scenario: apt script receives pre-generated sources.list +- **WHEN** a Debian or Ubuntu container is started +- **THEN** the Go test generates and mounts the `sources.list` file, and `test-apt.sh` removes interfering `sources.list.d/` entries, sets `DEBIAN_FRONTEND=noninteractive`, and runs `apt-get update` and `apt-get install` + +#### Scenario: DNF script handles both standard and COPR repos +- **WHEN** the Go test generates a `.repo` file with `gpgcheck=0` for COPR +- **THEN** `test-dnf.sh` uses the mounted repo config as-is, without modifying GPG settings + +### Requirement: Makefile e2e target with DISTRO and RELEASE parameters +The `make e2e` target SHALL accept optional `DISTRO` and `RELEASE` parameters. When `DISTRO` is set, it SHALL be converted to the corresponding test function name and passed via `-run`. When `RELEASE` is set, it SHALL be passed as the `E2E_RELEASE` environment variable. The target SHALL use a 15-minute timeout. + +#### Scenario: make e2e without parameters runs all tests +- **WHEN** a developer runs `make e2e` +- **THEN** all e2e test functions run with default releases and a 15-minute timeout -### Requirement: Shared cache directory across all distro tests -All distro subtests SHALL share a single temporary cache directory. Each repository writes to its own subdirectory within the cache (this is pkgproxy's default behavior). +#### Scenario: make e2e with DISTRO filters to one test +- **WHEN** a developer runs `make e2e DISTRO=fedora` +- **THEN** only `TestFedora` runs -#### Scenario: Cache directory is shared -- **WHEN** multiple distro subtests run sequentially -- **THEN** they all use the same cache directory passed to pkgproxy via `--cachedir` +#### Scenario: make e2e with DISTRO and RELEASE +- **WHEN** a developer runs `make e2e DISTRO=fedora RELEASE=42` +- **THEN** only `TestFedora` runs with `E2E_RELEASE=42` ### Requirement: Fedora e2e test -The test suite SHALL include a Fedora subtest using a `fedora:43` container that configures dnf to use pkgproxy for the `fedora` repository, refreshes metadata, and installs a small package (e.g. `tree`). GPG verification SHALL remain enabled. +The test suite SHALL include a top-level `TestFedora` test function using a `docker.io/library/fedora:` container (where release defaults to `43` or is set via `E2E_RELEASE`). The test SHALL configure dnf to use pkgproxy for the `fedora` repository and include a COPR subtest for `ganto/jo` using the `fedora-$releasever-$basearch` pattern. GPG verification SHALL remain enabled for the base repo, disabled for COPR. #### Scenario: Fedora metadata refresh succeeds - **WHEN** the Fedora container runs `dnf makecache` through pkgproxy @@ -61,36 +99,29 @@ The test suite SHALL include a Fedora subtest using a `fedora:43` container that #### Scenario: Fedora packages are cached - **WHEN** the Fedora package install completes -- **THEN** the cache directory contains at least one `.rpm` file under the `fedora/` subdirectory tree (recursive search) +- **THEN** the cache directory contains at least one `.rpm` file under the `fedora/` subdirectory tree -### Requirement: COPR e2e test -The test suite SHALL include a COPR subtest using the same `fedora:43` container that configures an additional dnf repository pointing at `ganto/jo` via the pkgproxy `copr` repository, and installs the `jo` package. GPG verification SHALL be disabled for the COPR repository (`gpgcheck=0`). - -#### Scenario: COPR package install succeeds +#### Scenario: Fedora COPR package install succeeds - **WHEN** the Fedora container runs `dnf install -y jo` from the COPR repository through pkgproxy -- **THEN** the command exits successfully - -#### Scenario: COPR packages are cached -- **WHEN** the COPR package install completes -- **THEN** the cache directory contains at least one `.rpm` file under the `copr/` subdirectory tree (recursive search) +- **THEN** the command exits successfully and cached `.rpm` files exist under the `copr/` cache subdirectory ### Requirement: Debian e2e test -The test suite SHALL include a Debian subtest using a `debian:trixie` container that configures apt to use pkgproxy for the `debian` and `debian-security` repositories, refreshes metadata, and installs a small package (e.g. `tree`). +The test suite SHALL include a top-level `TestDebian` test function using a `docker.io/library/debian:` container (where release defaults to `trixie` or is set via `E2E_RELEASE`). The test SHALL generate a `sources.list` in the Go test pointing at pkgproxy for the `debian` and `debian-security` repositories, mount it into the container, and install a small package. #### Scenario: Debian metadata refresh succeeds -- **WHEN** the Debian container runs `apt update` through pkgproxy +- **WHEN** the Debian container runs `apt-get update` through pkgproxy - **THEN** the command exits successfully #### Scenario: Debian package install succeeds -- **WHEN** the Debian container runs `apt install -y tree` through pkgproxy +- **WHEN** the Debian container runs `apt-get install -y tree` through pkgproxy - **THEN** the command exits successfully #### Scenario: Debian packages are cached - **WHEN** the Debian package install completes -- **THEN** the cache directory contains at least one `.deb` file under the `debian/` subdirectory tree (recursive search) +- **THEN** the cache directory contains at least one `.deb` file under the `debian/` subdirectory tree ### Requirement: Arch Linux e2e test -The test suite SHALL include an Arch Linux subtest using an `archlinux:latest` container that configures pacman to use pkgproxy for the `archlinux` repository, refreshes the package database, and installs a small package (e.g. `tree`). GPG verification SHALL remain enabled. +The test suite SHALL include a top-level `TestArch` test function using a `docker.io/library/archlinux:latest` container. The Arch Linux test SHALL NOT use `E2E_RELEASE` as Arch is a rolling release. GPG verification SHALL remain enabled. #### Scenario: Arch metadata refresh succeeds - **WHEN** the Arch container runs `pacman -Sy` through pkgproxy @@ -102,22 +133,45 @@ The test suite SHALL include an Arch Linux subtest using an `archlinux:latest` c #### Scenario: Arch packages are cached - **WHEN** the Arch package install completes -- **THEN** the cache directory contains at least one `.tar.zst` file under the `archlinux/` subdirectory tree (recursive search) +- **THEN** the cache directory contains at least one `.tar.zst` file under the `archlinux/` subdirectory tree -### Requirement: Per-distro-family shell scripts -The e2e tests SHALL use per-distro-family shell scripts (`test-dnf.sh`, `test-apt.sh`, `test-pacman.sh`) located in `test/e2e/` that are mounted into containers. Scripts SHALL accept parameters for proxy address and packages to install. +### Requirement: COPR e2e test +The COPR test SHALL be a subtest within each DNF-based distro's top-level test function rather than a standalone test. For Fedora, the COPR URL pattern SHALL be `/copr/ganto/jo/fedora-$releasever-$basearch/`. For non-Fedora DNF distros, the pattern SHALL be `/copr/ganto/jo/epel-$releasever-$basearch/`. GPG verification SHALL be disabled for COPR (`gpgcheck=0`). -#### Scenario: Shell script is mounted and executed -- **WHEN** a distro container is started -- **THEN** the corresponding shell script and repo config files are mounted into the container and the script is executed +#### Scenario: COPR package install succeeds within Fedora test +- **WHEN** `TestFedora` runs the COPR subtest +- **THEN** `jo` is installed from the COPR repository and cached `.rpm` files exist under the `copr/` subdirectory -#### Scenario: DNF script handles both standard and COPR repos -- **WHEN** the Go test generates a `.repo` file with `gpgcheck=0` for COPR -- **THEN** `test-dnf.sh` uses the mounted repo config as-is, without modifying GPG settings +#### Scenario: COPR package install succeeds within non-Fedora DNF test +- **WHEN** `TestAlmaLinux` runs the COPR subtest +- **THEN** `jo` is installed from the COPR repository using the `epel-$releasever-$basearch` URL pattern + +### Requirement: E2e test documentation in README.md +The `README.md` SHALL document how to run e2e tests via `make e2e` including the optional `DISTRO` and `RELEASE` parameters. It SHALL note that e2e tests should be extended when adding support for new Linux distributions. + +#### Scenario: Developer finds e2e test instructions in README +- **WHEN** a developer reads the README.md +- **THEN** they find instructions for running `make e2e`, `make e2e DISTRO=fedora`, and `make e2e DISTRO=fedora RELEASE=42` + +#### Scenario: README reminds to add e2e tests for new distros +- **WHEN** a developer reads the e2e testing section in README.md +- **THEN** they find guidance that adding support for a new Linux distribution requires adding corresponding e2e tests + +### Requirement: E2e test rules in CLAUDE.md +The `CLAUDE.md` SHALL list `make e2e` in the Commands section. The Rules section SHALL state that e2e tests must pass before a feature is considered complete. The Rules section SHALL state that adding support for a new Linux distribution requires adding corresponding e2e tests. The Rules section SHALL state that changes to client configuration snippets (e.g. `sources.list`, `.repo` files) must be replicated in the landing page snippets and in `README.md`. + +#### Scenario: CLAUDE.md commands include e2e +- **WHEN** Claude Code reads CLAUDE.md +- **THEN** `make e2e` is listed in the Commands section with usage examples + +#### Scenario: CLAUDE.md rules require e2e completion +- **WHEN** Claude Code checks the Rules section +- **THEN** it finds that e2e tests must pass before a feature is considered complete -### Requirement: Sequential distro test execution -Distro subtests SHALL run sequentially, not in parallel. +#### Scenario: CLAUDE.md rules require e2e for new distros +- **WHEN** Claude Code checks the Rules section +- **THEN** it finds that adding a new Linux distribution requires adding corresponding e2e tests -#### Scenario: Tests run one at a time -- **WHEN** the e2e test suite executes -- **THEN** each distro subtest completes before the next one starts +#### Scenario: CLAUDE.md rules require client config consistency +- **WHEN** Claude Code checks the Rules section +- **THEN** it finds that changes to client configuration snippets (sources.list, .repo files) must be replicated in the landing page snippets and in README.md