E2E test architecture
How CI runs E2E
The CI workflow .github/workflows/test.yml
(job call-agglayer-node-e2e-workflow) calls an external reusable workflow at
agglayer/e2e/.github/workflows/agglayer-node-e2e.yml.
It passes:
- A freshly built Docker image (via
docker-image-override: agglayer_image) - A pinned
kurtosis-cdk-refcommit - A pinned
agglayer-e2e-refcommit - A
kurtosis-cdk-argsJSON block configuring the network (includingl1_el_type,sequencer_type, andreth_imagefor the reth-based L1)
The workflow runs
bats tests/agglayer/bridges.bats tests/agglayer/rpc-tests.bats --filter-tags agglayer
in the agglayer/e2e repo.
The bridges.bats file covers L1/L2 bridging;
rpc-tests.bats validates reth-specific RPC methods
(e.g. eth_getTransactionBySenderAndNonce).
E2E jobs only trigger on merge_group and workflow_dispatch events,
not on pull_request.
See Validating E2E on a PR branch
for how to exercise them before merging.
Rules
The
agglayer/e2erepo bundles its own bats-support/bats-assert libraries incore/helpers/lib/.The tests use
polycli ulxly bridge assetandpolycli ulxly claim assetfor bridge operations.The test environment is bootstrapped by sourcing
tests/.envandcore/helpers/common.bash(_setup_vars), which auto-discovers RPC URLs, bridge addresses, and private keys from the running kurtosis enclave.All pinned commits and args live in
.github/workflows/test.yml; that is the single source of truth.Always ask whether to rebuild
agglayer:localbefore running. Recommend rebuilding (docker build -t agglayer:local .from the repo root) because skipping means the tests run against a stale image that does not reflect the current code.polycli version must match CI. The reusable workflow
agglayer/e2e/.github/workflows/agglayer-node-e2e.ymlpinsPOLYCLI_VERSION(e.g.v0.1.90) as an env var near the top. Install the matching release binary rather than building from source, becausemake installproduces the latest dev build which may have regressions (e.g. gas estimation changes that cause bridge tx reverts). To install a specific version:curl -sL "https://github.com/0xPolygon/polygon-cli/releases/download/${POLYCLI_VERSION}/polycli_${POLYCLI_VERSION}_linux_amd64.tar.gz" \ | tar xz -C ~/go/bin/ && mv ~/go/bin/polycli_* ~/go/bin/polyclipolyclilives at~/go/bin/polycliand is not on the default PATH. ExportPATH="$PATH:$HOME/go/bin"before running bats or any polycli commands.External repos are cached under
/tmp/agglayer-e2e/. Before cloning, check whether they already exist at the correct refs (comparegit -C <dir> rev-parse HEADwith the pinned SHA in.github/workflows/test.yml). Re-clone only if the ref has changed.The kurtosis args file at
/tmp/agglayer-e2e/kurtosis-args.jsonshould be checked/regenerated fromtest.ymleach run (ensure"agglayer_image": "agglayer:local"is present inargs).When e2e tests fail locally but pass in CI, check tool versions first. Compare local versions of polycli, kurtosis, bats, and foundry/cast against the versions CI installs (defined in
agglayer-node-e2e.yml). Version drift is a common root cause of otherwise-mysterious failures (e.g. gas estimation regressions, changed CLI flags).
For step-by-step local setup, see docs/knowledge-base/e2e-tests.md.
Validating E2E on a PR branch
E2E jobs only run on merge_group and workflow_dispatch events,
so they are skipped during normal PR CI.
To exercise them before the PR enters the merge queue,
trigger a workflow_dispatch run against the PR branch:
gh workflow run test.yml --repo agglayer/agglayer --ref <branch-name>
Monitor the run with:
gh run list --repo agglayer/agglayer --branch <branch-name> --workflow test.yml --limit 1
gh run view <run-id> --repo agglayer/agglayer --json jobs \
--jq '.jobs[] | "\(.name)\t\(.conclusion)"'
This run includes the full E2E suite (docker build + kurtosis + bats tests) and typically takes ~30 minutes.