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>
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
- Create
scenarios/<name>/dynamic.ymlandrun.sh(copystream-mode/as a template). - In
run.sh, define abodyfunction with the assertions and callrun_scenario "<name>" "$HERE" body. - Drive decisions with
lapi_add_decision <ip> [type] [duration]andlapi_delete_decision <ip>. - Add
<name>toE2E_MOCK_SCENARIOSin theMakefile.