Files
computer-playbook/.github/workflows/test-environment.yml
T
kevinveenbirkenbach f9f3dfd10d test(environment): differentiate cache assertions, split helpers, verify DiD path
Replace the previous OR-based assertion in scripts/tests/environment
(which trivially passed because the Nexus log always grows from
health probes) with a richer set of helpers split across two files
under utils/ for SRP/SPOT.

scripts/tests/environment/utils/cache.sh (new):

* expected_system_proxy_for_runtime maps DEV_RUNTIME_IMAGE to the
  Nexus proxy that handles its system package manager (apt-debian,
  apt-ubuntu, yum-fedora, yum-rocky; empty for Manjaro/Arch where
  pacman is not cached).
* nexus_repo_requests counts only /repository/<name>/... entries in
  the Nexus request log, optionally scoped to one proxy. Filters out
  health probes, admin REST calls, and Web-UI traffic.
* registry_cache_flows counts every cache-flow status (HIT, MISS,
  REVALIDATED, UPDATING, STALE) so cold deploys also count.
* assert_caches_used fails with a per-cache breakdown when any of
  three independent conditions is violated: total Nexus repo
  traffic = 0, the runtime's expected system proxy has 0 cached
  requests, or the deploy itself produced 0 registry-cache flows.
* probe_caches actively fetches a known upstream resource through
  each cache (apt-debian/dists/bookworm/Release for the package
  cache, /ca.crt for the registry cache).
* probe_did_inner_build drives a throwaway docker build whose
  apt-get update runs against deb.debian.org. The build container
  is placed on the compose network and pinned via --add-host to the
  frontend IP, exactly like the runtime override that
  roles/sys-svc-compose/files/compose.py injects for app builds.
  After the build the test snapshots
  ``docker logs infinito-package-cache-frontend`` and asserts the
  frontend recorded new requests, proving DiD apt traffic flows
  through nginx -> Nexus apt-debian and not directly to upstream.
  DOCKER_BUILDKIT=0 because BuildKit refuses --network=<compose-net>.

scripts/tests/environment/utils/common.sh (renamed from lib.sh):
keeps the bootstrap, constants, inventory inspect, and
assert_http_status; cache helpers moved out so the file is
single-concern.

scripts/tests/environment/07_deploy_minimal.sh sources both files;
order is snapshot, deploy, probe_caches, probe_did_inner_build,
snapshot, assert_caches_used. Active probes contribute traffic that
the AND assertion verifies, so the assertion is robust on deploys
that do not naturally trigger inner-build apt traffic.

.github/workflows/test-environment.yml: propagate DEV_RUNTIME_IMAGE
into the inner ``docker run`` so per-distro probe target and proxy
expectation resolve correctly inside the orchestrator.

.gitignore + .dockerignore: also ignore .claude/settings.local.json,
which compose mounts as /dev/null and which the classic docker
builder would otherwise try (and fail) to read into the build
context.

Verified end-to-end with five iterations of
``make act-workflow ACT_WORKFLOW=.github/workflows/test-environment.yml
ACT_JOB=test-environment ACT_MATRIX='dev_runtime_image:debian:bookworm'``.
The final iteration reports +81 apt-debian, +235 registry-cache
flows, +13 frontend log lines from the DiD probe, and "[OK] both
cache stacks observed activity" plus "[OK] DiD inner-build flowed
through cache frontend".
2026-05-01 10:25:45 +02:00

88 lines
3.2 KiB
YAML

name: "💻 Test: Development Environment"
on:
workflow_dispatch:
workflow_call:
permissions:
actions: write
contents: read
packages: read
jobs:
test-environment:
name: 🧑‍💻 Test Environment (${{ matrix.dev_runtime_image }})
runs-on: ubuntu-latest
timeout-minutes: 270
strategy:
fail-fast: false
matrix:
dev_runtime_image:
- manjarolinux/base
- debian:bookworm
- ubuntu:latest
- fedora:latest
- quay.io/centos/centos:latest
env:
DEV_RUNTIME_IMAGE: ${{ matrix.dev_runtime_image }}
NIX_CONFIG: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
# Cache caps for CI. The orchestrator unsets GITHUB_ACTIONS to
# simulate local dev, which activates the `cache` compose profile
# (registry-cache + package-cache). Bind paths moved to /mnt so
# caches share the 74g ephemeral disk with /var/lib/docker
# instead of stressing the small / partition. Sizes tuned for
# post-prune in-run re-pulls: large enough to fit one deploy's
# in-use image set (rpardini) plus pip/npm/apt artefacts (Nexus),
# leaving ~62g headroom for Docker layer storage on /mnt.
INFINITO_REGISTRY_CACHE_MAX_SIZE: 8g
INFINITO_REGISTRY_CACHE_HOST_PATH: /mnt/cache/registry/mirror
INFINITO_REGISTRY_CACHE_CA_HOST_PATH: /mnt/cache/registry/ca
INFINITO_PACKAGE_CACHE_BLOBSTORE_MAX: 4g
INFINITO_PACKAGE_CACHE_HEAP: 1g
INFINITO_PACKAGE_CACHE_DIRECT_MEM: 1g
INFINITO_PACKAGE_CACHE_HOST_PATH: /mnt/cache/package/data
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Run dev environment routine
shell: bash
run: |
set -euo pipefail
HOST_WORKDIR="$(pwd -P)"
# Build the development image in this job and avoid pulling mutable GHCR tags.
# Keep the same absolute path inside the container as on the host.
# This is required because docker compose talks to the host daemon via /var/run/docker.sock.
docker run --rm \
-e GITHUB_ACTIONS=true \
-e GITHUB_REPOSITORY="${{ github.repository }}" \
-e GITHUB_REPOSITORY_OWNER="${{ github.repository_owner }}" \
-e GITHUB_SHA="${{ github.sha }}" \
-e DEV_RUNTIME_IMAGE \
-e INFINITO_DISTRO=debian \
-e INFINITO_IMAGE=infinito-debian \
-e INFINITO_PULL_POLICY=never \
-e INFINITO_NO_BUILD=0 \
-e NIX_CONFIG \
-e INFINITO_REGISTRY_CACHE_MAX_SIZE \
-e INFINITO_REGISTRY_CACHE_HOST_PATH \
-e INFINITO_REGISTRY_CACHE_CA_HOST_PATH \
-e INFINITO_PACKAGE_CACHE_BLOBSTORE_MAX \
-e INFINITO_PACKAGE_CACHE_HEAP \
-e INFINITO_PACKAGE_CACHE_DIRECT_MEM \
-e INFINITO_PACKAGE_CACHE_HOST_PATH \
--network host \
-v "${HOST_WORKDIR}:${HOST_WORKDIR}" \
-v "/mnt/docker:/var/lib/docker" \
-v "/var/run/docker.sock:/var/run/docker.sock" \
-w "${HOST_WORKDIR}" \
"${DEV_RUNTIME_IMAGE}" \
bash -lc '
bash ./scripts/tests/environment/00_orchestrator.sh
'