Skip to content

Commit 99d1aad

Browse files
committed
feat(consume): consume direct using evmone-blockchaintest
1 parent 8b7d58c commit 99d1aad

File tree

4 files changed

+95
-29
lines changed

4 files changed

+95
-29
lines changed

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Test fixtures for use by clients are available for each release on the [Github r
2323

2424
- ✨ Add retry logic to RPC requests to fix flaky connection issues in Hive ([#2205](https://github.com/ethereum/execution-spec-tests/pull/2205)).
2525
- 🛠️ Mark `consume sync` tests as `flaky` with 3 retires due to client sync inconsistencies ([#2252](https://github.com/ethereum/execution-spec-tests/pull/2252)).
26+
- ✨ Add `consume direct` using `evmone-statetest` and `evmone-blockchaintest` ([#2243](https://github.com/ethereum/execution-spec-tests/pull/2243)).
2627

2728
### 📋 Misc
2829

docs/running_tests/consume/direct.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ uv run consume direct --bin=<evm-binary> [OPTIONS]
1515

1616
- go-ethereum `statetest` and `blocktest`
1717
- Nethermind `nethtest`
18-
- evmone `evmone-statetest`
18+
- evmone `evmone-statetest` and `evmone-blockchaintest`
1919

2020
## Advantages
2121

@@ -25,7 +25,7 @@ uv run consume direct --bin=<evm-binary> [OPTIONS]
2525

2626
## Limitations
2727

28-
- **Limited client support**: Only go-ethereum, Nethermind and (partially) evmone
28+
- **Limited client support**: Only go-ethereum, Nethermind and evmone
2929
- **Module scope**: Tests EVM, respectively block import, in isolation, not full client behavior.
3030
- **Interface dependency**: Requires client-specific test interfaces.
3131

@@ -46,7 +46,7 @@ uv run consume direct --input ./fixtures -m state_test --bin=nethtest
4646
or evmone:
4747

4848
```bash
49-
uv run consume direct --input ./fixtures -m state_test --bin=evmone-statetest
49+
uv run consume direct --input ./fixtures --bin=evmone-statetest --bin=evmone-blockchaintest
5050
```
5151

5252
Run fixtures in the blockchain test format for the Prague fork:

src/ethereum_clis/__init__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
)
1313
from .clis.besu import BesuTransitionTool
1414
from .clis.ethereumjs import EthereumJSTransitionTool
15-
from .clis.evmone import EvmoneExceptionMapper, EvmOneFixtureConsumer, EvmOneTransitionTool
15+
from .clis.evmone import (
16+
EvmOneBlockchainFixtureConsumer,
17+
EvmoneExceptionMapper,
18+
EvmOneStateFixtureConsumer,
19+
EvmOneTransitionTool,
20+
)
1621
from .clis.execution_specs import ExecutionSpecsTransitionTool
1722
from .clis.geth import GethFixtureConsumer, GethTransitionTool
1823
from .clis.nethermind import Nethtest, NethtestFixtureConsumer
@@ -31,7 +36,8 @@
3136
"EthereumJSTransitionTool",
3237
"EvmoneExceptionMapper",
3338
"EvmOneTransitionTool",
34-
"EvmOneFixtureConsumer",
39+
"EvmOneStateFixtureConsumer",
40+
"EvmOneBlockchainFixtureConsumer",
3541
"ExecutionSpecsTransitionTool",
3642
"FixtureConsumerTool",
3743
"GethFixtureConsumer",

src/ethereum_clis/clis/evmone.py

Lines changed: 83 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from pathlib import Path
1212
from typing import Any, ClassVar, Dict, List, Optional
1313

14+
import pytest
15+
1416
from ethereum_clis.file_utils import dump_files_to_directory
1517
from ethereum_clis.fixture_consumer_tool import FixtureConsumerTool
1618
from ethereum_test_exceptions import (
@@ -20,6 +22,7 @@
2022
TransactionException,
2123
)
2224
from ethereum_test_fixtures.base import FixtureFormat
25+
from ethereum_test_fixtures.blockchain import BlockchainFixture
2326
from ethereum_test_fixtures.state import StateFixture
2427
from ethereum_test_forks import Fork
2528

@@ -54,26 +57,19 @@ def is_fork_supported(self, fork: Fork) -> bool:
5457
return True
5558

5659

57-
class EvmOneFixtureConsumer(
58-
FixtureConsumerTool,
59-
fixture_formats=[StateFixture],
60-
):
61-
"""Evmone's implementation of the fixture consumer."""
60+
class EvmoneFixtureConsumerCommon:
61+
"""Common functionality for Evmone fixture consumers."""
6262

63-
default_binary = Path("evmone-statetest")
64-
detect_binary_pattern = re.compile(r"^evmone-statetest\b")
63+
binary: Path
6564
version_flag: str = "--version"
6665

67-
binary: Path
6866
cached_version: Optional[str] = None
6967

7068
def __init__(
7169
self,
72-
binary: Optional[Path] = None,
7370
trace: bool = False,
7471
):
75-
"""Initialize the EvmOneFixtureConsumer class."""
76-
self.binary = binary if binary else self.default_binary
72+
"""Initialize the EvmoneFixtureConsumerCommon class."""
7773
self._info_metadata: Optional[Dict[str, Any]] = {}
7874

7975
def _run_command(self, command: List[str]) -> subprocess.CompletedProcess:
@@ -126,19 +122,22 @@ def _consume_debug_dump(
126122
)
127123
shutil.copyfile(fixture_path, debug_fixture_path)
128124

125+
def _skip_message(self, fixture_format: FixtureFormat) -> str:
126+
return f"Fixture format {fixture_format.format_name} not supported by {self.binary}"
127+
129128
@cache # noqa
130-
def consume_state_test_file(
129+
def consume_test_file(
131130
self,
132131
fixture_path: Path,
133132
debug_output_path: Optional[Path] = None,
134133
) -> Dict[str, Any]:
135134
"""
136-
Consume an entire state test file.
135+
Consume an entire state or blockchain test file.
137136
138-
The `evmone-statetest` will always execute all the tests contained in a
137+
The `evmone-...test` will always execute all the tests contained in a
139138
file without the possibility of selecting a single test, so this
140139
function is cached in order to only call the command once and
141-
`consume_state_test` can simply select the result that was requested.
140+
`consume_test` can simply select the result that was requested.
142141
"""
143142
global_options: List[str] = []
144143
if debug_output_path:
@@ -160,7 +159,9 @@ def consume_state_test_file(
160159
try:
161160
output_data = json.load(tempfile_json)
162161
except json.JSONDecodeError as e:
163-
raise Exception(f"Failed to parse JSON output from evmone-statetest: {e}") from e
162+
raise Exception(
163+
f"Failed to parse JSON output from evmone-state/blockchaintest: {e}"
164+
) from e
164165

165166
if debug_output_path:
166167
self._consume_debug_dump(command, result, fixture_path, debug_output_path)
@@ -173,19 +174,19 @@ def _failure_msg(self, file_results: Dict[str, Any]) -> str:
173174
failures = file_results["testsuites"][0]["testsuite"][0]["failures"]
174175
return ", ".join([f["failure"] for f in failures])
175176

176-
def consume_state_test(
177+
def consume_test(
177178
self,
178179
fixture_path: Path,
179180
fixture_name: Optional[str] = None,
180181
debug_output_path: Optional[Path] = None,
181182
):
182183
"""
183-
Consume a single state test.
184+
Consume a single state or blockchain test.
184185
185-
Uses the cached result from `consume_state_test_file` in order to not
186+
Uses the cached result from `consume_test_file` in order to not
186187
call the command every time an select a single result from there.
187188
"""
188-
file_results = self.consume_state_test_file(
189+
file_results = self.consume_test_file(
189190
fixture_path=fixture_path,
190191
debug_output_path=debug_output_path,
191192
)
@@ -205,6 +206,26 @@ def consume_state_test(
205206
f"Test name mismatch, expected {fixture_path.stem}, got {test_name}"
206207
)
207208

209+
210+
class EvmOneStateFixtureConsumer(
211+
EvmoneFixtureConsumerCommon,
212+
FixtureConsumerTool,
213+
fixture_formats=[StateFixture],
214+
):
215+
"""Evmone's implementation of the fixture consumer for state tests."""
216+
217+
default_binary = Path("evmone-statetest")
218+
detect_binary_pattern = re.compile(r"^evmone-statetest\b")
219+
220+
def __init__(
221+
self,
222+
binary: Optional[Path] = None,
223+
trace: bool = False,
224+
):
225+
"""Initialize the EvmOneStateFixtureConsumer class."""
226+
self.binary = binary if binary else self.default_binary
227+
super().__init__(trace=trace)
228+
208229
def consume_fixture(
209230
self,
210231
fixture_format: FixtureFormat,
@@ -213,19 +234,57 @@ def consume_fixture(
213234
debug_output_path: Optional[Path] = None,
214235
):
215236
"""
216-
Execute the appropriate geth fixture consumer for the fixture at
237+
Execute the appropriate fixture consumer for the fixture at
217238
`fixture_path`.
218239
"""
219240
if fixture_format == StateFixture:
220-
self.consume_state_test(
241+
self.consume_test(
221242
fixture_path=fixture_path,
222243
fixture_name=fixture_name,
223244
debug_output_path=debug_output_path,
224245
)
225246
else:
226-
raise Exception(
227-
f"Fixture format {fixture_format.format_name} not supported by {self.binary}"
247+
pytest.skip(self._skip_message(fixture_format))
248+
249+
250+
class EvmOneBlockchainFixtureConsumer(
251+
EvmoneFixtureConsumerCommon,
252+
FixtureConsumerTool,
253+
fixture_formats=[BlockchainFixture],
254+
):
255+
"""Evmone's implementation of the fixture consumer for blockchain tests."""
256+
257+
default_binary = Path("evmone-blockchaintest")
258+
detect_binary_pattern = re.compile(r"^evmone-blockchaintest\b")
259+
260+
def __init__(
261+
self,
262+
binary: Optional[Path] = None,
263+
trace: bool = False,
264+
):
265+
"""Initialize the EvmOneBlockchainFixtureConsumer class."""
266+
self.binary = binary if binary else self.default_binary
267+
super().__init__(trace=trace)
268+
269+
def consume_fixture(
270+
self,
271+
fixture_format: FixtureFormat,
272+
fixture_path: Path,
273+
fixture_name: Optional[str] = None,
274+
debug_output_path: Optional[Path] = None,
275+
):
276+
"""
277+
Execute the appropriate fixture consumer for the fixture at
278+
`fixture_path`.
279+
"""
280+
if fixture_format == BlockchainFixture:
281+
self.consume_test(
282+
fixture_path=fixture_path,
283+
fixture_name=fixture_name,
284+
debug_output_path=debug_output_path,
228285
)
286+
else:
287+
pytest.skip(self._skip_message(fixture_format))
229288

230289

231290
class EvmoneExceptionMapper(ExceptionMapper):

0 commit comments

Comments
 (0)