Skip to content

Add E2E settlement tests and CI workflow#46

Merged
chudkowsky merged 16 commits intomainfrom
feat/e2e-test
Feb 23, 2026
Merged

Add E2E settlement tests and CI workflow#46
chudkowsky merged 16 commits intomainfrom
feat/e2e-test

Conversation

@chudkowsky
Copy link
Copy Markdown
Collaborator

@chudkowsky chudkowsky commented Feb 23, 2026

Summary

First iteration of E2E settlement tests running natively on the CI runner against a Docker Compose infrastructure stack.

Changes

New crate: saya-e2e

  • Query utilities for the Piltover settlement contract (get_program_info, get_facts_registry, get_settlement_state, wait_for_settlement)
  • Environment helpers (settlement_rpc_url, piltover_address, etc.) with sensible defaults

Tests (tests/settlement.rs)

  • test_program_info_and_fact_registry: smoke-tests that deploy/setup scripts produced the correct on-chain contract configuration
  • test_settlement_advances_after_genesis: waits up to 120s for saya to settle at least one block past genesis

Docker Compose (compose.yml)

Orchestrates the full infrastructure stack:

  • katana_bootstrap (L1 settlement chain)
  • Contract setup pipeline: fact-registry-setupcore_contract_declarecore_contract_deploycore_contract_setup
  • katana_init + katana_l3 (rollup chain)
  • saya (starts once both chains are healthy)

CI Workflow (.github/workflows/e2e-tests.yml)

  • Installs Rust 1.87 with Swatinem/rust-cache for persistent build caching
  • Starts the compose stack in detached mode
  • Polls until the saya container is running, then runs cargo test natively
  • Tests reach katana_bootstrap via localhost:5050 (already exposed on the host)
  • Collects and uploads compose logs on failure

Testing notes

  • Tests are async tokio; wait_for_settlement handles saya startup timing
  • Assertion on settlement only checks that genesis was passed, not a specific block number (avoids flakiness from polling races)

chudkowsky and others added 16 commits February 12, 2026 14:06
- Add saya-e2e test crate with settlement contract validation tests
- test_piltover_initial_state: validates genesis block state (block_number = Felt::MAX)
- test_program_info_and_fact_registry: verifies contract config matches expected values
- test_settlement_advances_after_genesis: confirms settlement state advances after genesis
- Add environment configuration helpers (chain_id, piltover_address, fact_registry_address, fee_token_address)
- Add Piltover contract reader utilities (get_program_info, get_facts_registry, get_settlement_state, wait_for_settlement)
- Split compose into e2e-tests-pre (static checks) and e2e-tests (settlement checks) phases
- Add GitHub Actions workflow for CI: runs on push/PR to main, uses docker compose up with proper service dependencies
- Workflow kills all containers on completion to prevent resource leaks
Replace blind `sleep 10` with an `until curl` retry loop in
fact-registry-setup and core_contract_declare, which are the two
services that race directly against katana_bootstrap becoming healthy.
Also revert core_contract_deploy and core_contract_setup back to YAML
array form since they only start after prior services complete and DNS
is already stable by then.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Increase katana_bootstrap healthcheck retries 10->30 and add
  start_period: 10s so slow GH Actions runners don't exhaust retries
  before katana finishes booting
- Add 60s timeout to the until-curl loops in fact-registry-setup and
  core_contract_declare so a DNS failure exits loudly instead of
  hanging until the job timeout

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
$WAITED was being consumed by Docker Compose variable interpolation
before the shell ran, resulting in "[: Illegal number:". Use $$WAITED
and $$((WAITED+1)) so compose passes them through as literal $WAITED.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…tion

Container name resolution fails on GitHub Actions when images ship with
a custom /etc/resolv.conf. Setting dns: 127.0.0.11 (Docker's embedded
DNS) on all services and anchors overrides whatever the image ships with
and ensures katana_bootstrap/katana_l3 resolve within the saya_net network.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
curl is not present in the saya image. Use bash's built-in /dev/tcp
to test TCP connectivity to katana_bootstrap:5050 instead — bash and
timeout are both available in the image.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
--exit-code-from implies --abort-on-container-exit, which kills all
containers the moment the first one exits — including successful setup
containers like core_contract_declare. Switch to `docker compose up -d`
+ `docker compose wait e2e-tests` so one-shot setup containers can
exit normally without aborting the rest of the pipeline.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
dns: 127.0.0.11 breaks external DNS resolution needed by rustup to
sync the toolchain from static.rust-lang.org. The e2e-tests-pre and
e2e-tests containers run late in the pipeline when katana_bootstrap
has been up long enough for Docker's default DNS to resolve it.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Remove e2e-tests-pre and e2e-tests Docker containers in favour of
running cargo test directly on the GitHub Actions runner:
- Cargo build cache via Swatinem/rust-cache persists across runs
- No rustup toolchain downloads inside Docker
- Tests reach katana_bootstrap via localhost:5050 (already exposed)
- Workflow waits for the saya container to be running before testing
- Remove unused e2e-cargo-registry/git/target named volumes

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Drop test_piltover_initial_state and the pre/post-saya split.
Both remaining tests run after saya is up — test_program_info_and_fact_registry
checks static contract state (valid at any point) and
test_settlement_advances_after_genesis has its own wait loop.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
assert_eq!(settled, 0) would fail if saya settles block 0 before the
test polls — any block >= 0 proves settlement advanced past genesis.
wait_for_settlement already encodes this invariant; just verify the
conversion succeeds.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@chudkowsky chudkowsky merged commit c38b7ba into main Feb 23, 2026
5 of 6 checks passed
@chudkowsky chudkowsky deleted the feat/e2e-test branch February 23, 2026 22:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant