Methods of Running Tests¶
EEST has two commands, consume
and execute
, that run test cases against EL clients:
consume
runs JSON test fixtures against a client - the client is said to "consume" the test case fixture.execute
runs test cases from Python source against a client - the test case is "executed" against the client.
Top-Level Comparison¶
Both consume
and execute
provide sub-commands which correspond to different methods of testing EL clients using EEST test cases:
Command | Description | Components tested | Environment | Scope |
---|---|---|---|---|
consume direct |
Client consume tests via a statetest interface |
EVM | None | Module test |
consume direct |
Client consume tests via a blocktest interface |
EVM, block processing | None | Module test,Integration test |
consume engine |
Client imports blocks via Engine API EngineNewPayload in Hive |
EVM, block processing, Engine API | Staging, Hive | System test |
consume rlp |
Client imports RLP-encoded blocks upon start-up in Hive | EVM, block processing, RLP import (sync*) | Staging, Hive | System test |
execute hive |
Tests executed against a client via JSON RPC eth_sendRawTransaction in Hive |
EVM, JSON RPC, mempool | Staging, Hive | System test |
execute remote |
Tests executed against a client via JSON RPC eth_sendRawTransaction on a live network |
EVM, JSON RPC, mempool, EL-EL/EL-CL interaction (indirectly) | Production | System Test |
*sync: Depending on code paths used in the client implementation, see the RLP vs Engine Simulator section below.
The following sections describe the different methods in more detail.
./hive --sim=eest/consume-engine
vs consume engine
EEST simulators can be ran either standalone using the ./hive
command or via an EEST command against a ./hive --dev
backend, more details are provided below.
Direct¶
Nomenclature | |
---|---|
Command | consume direct |
Simulator | None |
Fixture Formats | state_test ,blockchain_test |
The direct method provides the fastest way to test EVM functionality by executing tests directly through a client's dedicated test interface (e.g. statetest
or blocktest
). This method requires clients to implement a custom interface to read tests and pass their inputs through appropriate code paths; implementation guides available for state tests and blockchain tests.
The EEST consume direct
command is a small wrapper around client direct interfaces that allows fast and easy selection of test subsets to execute via test ID regex match (thanks to an index file). See Consume Direct and the Cache and Fixture Inputs and Useful Pytest Options pages for help with options.
Rapid EVM development
The direct
method with the StateTest
format should be used for the fastest EVM development feedback loop. Additionally, EVM traces can be readily generated and compared to other implementations.
Engine¶
Nomenclature | |
---|---|
Command | consume engine |
Simulator | eest/consume-engine |
Fixture format | blockchain_test_engine |
The consume engine method tests execution clients via the Engine API by sending block payloads and verifying the response (post-merge forks only). This method provides the most realistic testing environment for production Ethereum client behavior, covering consensus integration, payload validation, and state synchronization.
The consume engine
command:
- Initializes the execution client with genesis state.
- Connects via Engine API (port 8551), primitively mocking a consensus client.
- Sends a forkchoice update to establish the chain head.
- Submits payloads using
engine_newPayload
calls. - Validates responses against expected results.
- Tests error conditions and exception handling.
RLP¶
Nomenclature | |
---|---|
Command | consume rlp |
Simulator | eest/consume-rlp |
Fixture format | blockchain_test |
The RLP consumption method tests execution clients by providing them with RLP-encoded blocks to load upon startup, similar to the block import process during historical synchronization. This method tests the client's core block processing logic without the overhead of network protocols.
The consume rlp
command:
- Reads blockchain test fixtures from the specified input source.
- Extracts RLP-encoded blocks from the fixture files.
- Copies blocks to the client's container via files in the
/blocks/
directory. - Starts the client with the genesis state and block files.
- Validates the client's final
blockHash
via JSON RPC against the test's expectations.
This method simulates how clients import blocks during historical sync, testing the complete block validation and state transition pipeline, see below for more details and a comparison to consumption via the Engine API.
Engine vs RLP Simulator¶
The RLP Simulator (eest/consume-rlp
) and the Engine Simulator (eest/consume-engine
) should be seen as complimentary to one another. Although they execute the same underlying EVM test cases, the block validation logic is executed via different client code paths (using different fixture formats). Therefore, ideally, both simulators should be executed for full coverage.
Code Path Choices¶
Clients consume fixtures in the eest/consume-engine
simulator via the Engine API's EngineNewPayloadv*
endpoint; a natural way to validate, respectively invalidate, block payloads. In this case, there is no flexibility in the choice of code path - it directly harnesses mainnet client functionality. The eest/consume-rlp
Simulator, however, allows clients more freedom, as the rlp-encoded blocks are imported upon client startup. Clients are recommended to try and hook the block import into the code path used for historical syncing.
Differences¶
eest/consume-rlp |
eest/consume-engine |
|
---|---|---|
Fixture Format Used | BlockchainTest |
BlockchainTestEngine |
Fork support | All forks (including pre-merge) | Post-merge forks only (Paris+) |
Client code path | Historical sync / block import pipeline | Engine API / consensus integration |
Real-world analogy | Blocks received during sync | Blocks received from consensus client |
Interface | Block import upon start-up via RLP files | Engine API calls (newPayload , forkchoiceUpdated ) |
Exception testing | Basic exception handling | Advanced exception verification with client-specific mappers |
Running both simulators adds some redundancy that can assist test debugging
If Engine tests fail but RLP tests pass, the issue is likely in your Engine API implementation rather than core EVM logic.
Execute¶
See Execute Command.
Two Methods to Run EEST Simulators¶
Many of the methods use the Hive Testing Environment to interact clients and run tests against them. These methods are also called Hive simulators. While Hive is always necessary to run simulators, they can be called in two different ways. Both of these commands execute the same simulator code, but in different environments, we take the example of the eest/consume-engine
simulator:
./hive --sim=eest/consume-engine
is a standalone command that installs EEST and theconsume
command in a dockerized container managed by Hive. This is the standard method to execute EEST fixture releases against clients in CI environments and is the method to generate the results at hive.ethpandaops.io. See Hive and its Common Options for help with this method.uv run consume engine
requires the user to clone and install EEST and start a Hive server in development mode. In this case, the simulator runs on the native system and communicate to the client via the Hive API. This is particularly useful during test development as fixtures on the local disk can be specified via--input=fixtures/
. As the simulator runs natively, it is easy to drop into a debugger and inspect the simulator or client container state. See Hive Developer Mode for help with this method.