Assertoor is a full-scale testing orchestrator for live Ethereum testnets, built in Go. It manages test playbooks that verify network behavior by executing task-based workflows against consensus and execution layer clients.
main.go -> cmd/root.go -> pkg/assertoor/Coordinator
|- ClientPool (consensus + execution RPC clients)
|- TestRegistry (loads test definitions from YAML)
|- TestRunner (executes tests with task scheduler)
|- Database (SQLite/PostgreSQL persistence)
|- WebServer (REST API + React frontend)
|- EventBus (coordinator-wide events)
|- Spamoor (transaction generation engine)
cmd/- CLI commands (root, tasks, validate)pkg/assertoor/- Coordinator, config loading, test registrypkg/clients/- Consensus and execution client pool managementpkg/scheduler/- Task execution engine, state machine, variable scopingpkg/tasks/- 41+ task implementations (check, generate, flow, utility)pkg/test/- Test runner, descriptor, lifecycle managementpkg/types/- Core interfaces (Task, Test, Coordinator, Variables)pkg/vars/- Variable system with jq expression evaluationpkg/txmgr/- Transaction manager (Spamoor wrapper)pkg/db/- Database layer with migrationspkg/web/- REST API with Swagger docsplaybooks/- Pre-built test playbooks organized by network typeweb-ui/- React/TypeScript frontend
See .ai/PLAYBOOK_AUTHORING.md for complete playbook writing guide.
See .ai/TASK_REFERENCE.md for detailed task documentation with all config parameters and outputs.
make build # Compile binary to bin/assertoor
make test # Run Go tests
make docs # Generate Swagger API docs
make ui # Build web UI
make devnet # Start local devnet
make devnet-run # Run assertoor against local devnetMain config file (YAML):
coordinator- max concurrent tests, retentionweb- server host/port, API/frontend togglesendpoints- array of {name, executionUrl, consensusUrl}validatorNames- inventory for mapping validator indices to namesglobalVars- variables available to all teststests/externalTests- test definitions or file references
- Hierarchical scoping: global -> test -> task -> child task
- jq expression evaluation via
configVarsmappings - Placeholder syntax:
${varname}(simple) or${{.query}}(jq expression) - Task outputs accessible via
tasks.<taskId>.outputs.<variable> - Task status via
tasks.<taskId>.result(0=None, 1=Success, 2=Failure)