Files
crowdsec-bouncer-traefik-pl…/tests/e2e/mock
mhxandClaude Opus 4.8 070a82992a ⬇️ e2e mock: keep Go floor at 1.22 (yaegi ceiling)
Revert the mock module back to go 1.22 and make the e2e workflow read the Go
version from go.mod (go-version-file) instead of hardcoding 1.23.

Rationale: the plugin is interpreted by yaegi, and even Traefik v3.7.1 ships
yaegi v0.16.1 (Go 1.22), so the project stays on 1.22. The earlier bump to 1.23
is dropped (plugin go.mod stays 1.22, see #330 for the Renovate cap + CI pin).
Mock + all six scenarios verified on Go 1.22.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 12:03:19 +02:00
..
2026-06-06 12:03:19 +02:00

Binary e2e suite (Traefik binary + mock LAPI)

This suite runs Traefik as a downloaded binary with the plugin loaded from the local source tree, and replaces Crowdsec with a small HTTP mock (mocklapi/, a stdlib-only Go command). No Docker, no real Crowdsec.

It is what CI runs (make e2e_mock). A separate, local-only Docker suite (real Traefik + Crowdsec, under tests/e2e/scenarios) is kept for high-fidelity debugging against a real Crowdsec but is not exercised in CI; it ships in its own PR (#333).

Scope — what this suite does and does NOT test

These tests validate the plugin's own behaviour: the request flow through the Traefik middleware, the live / none / stream modes, caching, trusted-IP bypass, and ban / captcha page rendering.

They deliberately do not test that Crowdsec or its AppSec engine work correctly — that is validated and owned by the upstream maintainer (@maxlerebourg), not by this plugin. The mock only emulates the slice of the LAPI HTTP contract the plugin consumes.

So please don't open issues here about Crowdsec/AppSec detection accuracy based on this suite: the AppSec scenario is intentionally absent, and the mock returns whatever decisions the test tells it to.

What runs

Component How
Traefik Binary v3.7.1, downloaded into .cache/ (reused across local runs; re-downloaded on fresh CI runners)
Plugin Loaded via experimental.localPlugins from the repo root (symlinked into plugins-local/)
LAPI mocklapi — a stdlib-only Go command (its own nested module), compiled and cached under .cache/, driven through /admin endpoints instead of cscli
Backend A plain HTTP responder built into the mock

Fixed ports (override with env vars if needed): Traefik 8000, LAPI 8090, backend 8091.

Running locally

Prerequisites: bash, curl, go, tar. On first use the Traefik binary is fetched and the mock is compiled into .cache/. That cache is reused across local runs; CI runs on fresh runners, so both are recreated on every CI run.

# one scenario
make e2e_mock_stream-mode
# or directly
./tests/e2e/mock/scenarios/stream-mode/run.sh

# the whole suite
make e2e_mock

Layout

mock/
  lib/
    common.sh     # stack lifecycle, Traefik download, mock build, assertions, admin client
    traefik.yml   # static Traefik config (shared by all scenarios)
  mocklapi/
    go.mod        # nested module — kept out of the plugin's build/lint/vendor
    main.go       # mock LAPI + backend
  scenarios/
    <name>/
      dynamic.yml # Traefik dynamic config (router + bouncer middleware + backend)
      run.sh      # assertions for the scenario
      *.html      # optional fixtures (ban / captcha templates)

dynamic.yml uses placeholders (@@APIKEY@@, @@LAPI_HOST@@, @@BACKEND_URL@@, @@SCENARIO_DIR@@) that common.sh substitutes at runtime.

Adding a scenario

  1. Create scenarios/<name>/dynamic.yml and run.sh (copy stream-mode/ as a template).
  2. In run.sh, define a body function with the assertions and call run_scenario "<name>" "$HERE" body.
  3. Drive decisions with lapi_add_decision <ip> [type] [duration] and lapi_delete_decision <ip>.
  4. Add <name> to E2E_MOCK_SCENARIOS in the Makefile.