From 33def87c30cf8a9de53ee5d8054768d9fca26e7f Mon Sep 17 00:00:00 2001 From: mhx Date: Thu, 4 Jun 2026 19:14:37 +0200 Subject: [PATCH] :recycle: tests: run e2e suite in a single sequential job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The matrix spawned one runner per scenario, so the Traefik, Crowdsec and whoami images were pulled — and Crowdsec booted — once per scenario. Run the whole suite in a single job with `make -k e2e` instead: Docker caches the images locally so they are pulled only once, and `-k` keeps the remaining scenarios running after a failure (make still exits non-zero). Scenarios already share the canonical `crowdsec` container name and the 8000 port, so they were meant to run sequentially anyway. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/e2e.yml | 26 ++++++++++---------------- tests/e2e/README.md | 23 +++++++++++++---------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 2e15a59..0d2f459 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -14,27 +14,21 @@ permissions: jobs: e2e: - name: ${{ matrix.scenario }} + name: e2e runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - scenario: - - stream-mode - - live-mode - - none-mode - - trusted-ips - - custom-ban-page - - captcha - - appsec steps: - uses: actions/checkout@v6 - - name: Run scenario - run: ./tests/e2e/scenarios/${{ matrix.scenario }}/run.sh + # A single runner runs every scenario sequentially. Docker caches the + # Traefik/Crowdsec/whoami images locally, so they are pulled only once + # for the whole suite instead of once per scenario. `-k` keeps going + # after a failing scenario so the logs cover all of them, while make + # still exits non-zero if any scenario failed. + - name: Run scenarios + run: make -k e2e - name: Upload logs on failure if: failure() uses: actions/upload-artifact@v4 with: - name: logs-${{ matrix.scenario }} - path: /tmp/e2e-${{ matrix.scenario }}.log + name: e2e-logs + path: /tmp/e2e-*.log if-no-files-found: ignore diff --git a/tests/e2e/README.md b/tests/e2e/README.md index b991e72..a707288 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -28,22 +28,25 @@ Run everything: make e2e ``` -Each scenario uses an isolated Docker Compose project (`-p e2e-`), -so multiple scenarios can run in parallel without colliding on container -names — except for the `crowdsec` container, which keeps its canonical -name so `cscli` commands work uniformly across scenarios. Run scenarios -serially if you need to invoke them on the same host at the same time. +Scenarios run **sequentially** on a single host: they share the canonical +`crowdsec` container name (so `cscli` commands work uniformly) and the same +`8000:80` port. Each scenario uses its own Docker Compose project +(`-p e2e-`) and tears its stack down on exit, so the next one +starts clean. `make e2e` runs them one after another; Docker reuses the +images pulled by the first scenario, so the Traefik / Crowdsec / whoami +images are downloaded only once for the whole suite. ## Writing a new scenario 1. Copy `scenarios/stream-mode/` as a template. 2. Rename `container_name`s (keep `crowdsec` for the LAPI container). 3. Edit `run.sh` to express the behavior under test. -4. Add the scenario name to the `matrix` in `.github/workflows/e2e.yml` - and to `E2E_SCENARIOS` in the `Makefile`. +4. Add the scenario name to `E2E_SCENARIOS` in the `Makefile`. ## CI -`.github/workflows/e2e.yml` runs one parallel job per scenario on every -PR and push to `main`. On failure, container logs are uploaded as an -artifact named `logs-`. +`.github/workflows/e2e.yml` runs the whole suite in a single job +(`make -k e2e`) on every PR and push to `main`. `-k` lets the remaining +scenarios run after a failure so the logs cover all of them, while make +still exits non-zero if any scenario failed. On failure, the per-scenario +logs (`/tmp/e2e-*.log`) are uploaded as an artifact named `e2e-logs`.