Skip to content

feat(consume): add consume enginex simulator #1765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a06facf
refactor(consume): rename `hive_simulators` to `simulators`.
danceratopz Jun 13, 2025
26552ce
refactor(consume): move helper modules to a new `helpers` sub-package
danceratopz Jun 13, 2025
5a7bb7c
refactor(consume): rename `conftest` to `single_test_client` plugin
danceratopz Jun 13, 2025
00aa6a6
refactor(consume): split into separate plugins by functionality
danceratopz Jun 13, 2025
bfdb1f8
refactor(consume): split base functionality out to the `base` plugin
danceratopz Jun 13, 2025
c94da10
fix(consume): add `genesis_header` to `single_test_cilent` plugin
danceratopz Jun 18, 2025
f959d23
refactor(consume): move test execution files to shared hive_tests dir…
danceratopz Jun 25, 2025
99638fc
fix(consume): add explicit plugin registration for simulator-specific…
danceratopz Jun 25, 2025
b610953
docs: add changelog entry for consume simulator refactor (#1801)
danceratopz Jun 25, 2025
97a2857
feat(consume): add initial implementation of consume enginex
danceratopz Jun 18, 2025
ade2bf7
fix(consume): update according to renaming in #1760
danceratopz Jun 18, 2025
7946876
refactor(consume): rename & simplify consume enginex command
danceratopz Jun 18, 2025
ea65be3
refactor(consume): rename simulator path to enginex
danceratopz Jun 18, 2025
26d64c9
refactor(consume): rename/update w/enginex & pre-alloc group terminology
danceratopz Jun 18, 2025
4840c88
feat(consume): track tests by pre-alloc group for client cleanup
danceratopz Jun 18, 2025
307bd52
feat(consume): add `--enginex-fcu-frequency` option
danceratopz Jun 18, 2025
0cda5ee
feat(consume): append enginexfixture pre_hash field to testid if avai…
danceratopz Jun 20, 2025
f467407
fix(consume): explicitly depend on hive_test fixture for result propa…
danceratopz Jun 20, 2025
f62dda4
feat(consume): create pre_hash subgroups w/max size for better xdist …
danceratopz Jun 20, 2025
4b5e3ac
fix(consume): recognize `--enginex-max-group-size` option in consume.…
danceratopz Jun 20, 2025
a92a13c
fix(consume): more bugfixes for creating pre_hash group subgroups & l…
danceratopz Jun 20, 2025
8cb47da
fix(consume): fix test group/client clean-up tracking after introduct…
danceratopz Jun 23, 2025
68ef8cc
refactor(consume): move pytest_hive plugin registration to simulator …
danceratopz Jun 25, 2025
eb0ab02
refactor(consume): add pytest_hive plugin to enginex simulator conftest
danceratopz Jun 25, 2025
6e7e28d
fix(consume): use parameter-based test discovery in pytest_generate_t…
danceratopz Jun 25, 2025
c49dd35
refactor(consume): use fixture format detection for enginex parametri…
danceratopz Jun 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Users can select any of the artifacts depending on their testing needs for their

#### `consume`

- 🔀 Refactor consume simulator architecture to use explicit pytest plugin structure with forward-looking architecture ([#1801](https://github.com/ethereum/execution-spec-tests/pull/1801)).

#### `execute`

- ✨ Add `blob_transaction_test` execute test spec, which allows tests that send blob transactions to a running client and verifying its `engine_getBlobsVX` endpoint behavior ([#1644](https://github.com/ethereum/execution-spec-tests/pull/1644)).
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ classifiers = [
dependencies = [
"click>=8.1.0,<9",
"ethereum-execution==1.17.0rc6.dev1",
"hive.py @ git+https://github.com/marioevz/hive.py",
"hive-py",
"ethereum-spec-evm-resolver",
"gitpython>=3.1.31,<4",
"PyJWT>=2.3.0,<3",
Expand Down Expand Up @@ -147,4 +147,5 @@ check-filenames = true
ignore-words-list = "ingenuous"

[tool.uv.sources]
ethereum-spec-evm-resolver = { git = "https://github.com/spencer-tb/ethereum-spec-evm-resolver", rev = "ee273e7344e24a739ebfbf0ea1f758530c4d032b" }
ethereum-spec-evm-resolver = { git = "https://github.com/spencer-tb/ethereum-spec-evm-resolver", rev = "ee273e7344e24a739ebfbf0ea1f758530c4d032b" }
hive-py = { git = "https://github.com/marioevz/hive.py", rev = "582703e2f94b4d5e61ae495d90d684852c87a580" }
6 changes: 3 additions & 3 deletions pytest-framework.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ addopts =
--ignore=src/pytest_plugins/consume/test_cache.py
--ignore=src/pytest_plugins/consume/direct/
--ignore=src/pytest_plugins/consume/direct/test_via_direct.py
--ignore=src/pytest_plugins/consume/hive_simulators/
--ignore=src/pytest_plugins/consume/hive_simulators/engine/test_via_engine.py
--ignore=src/pytest_plugins/consume/hive_simulators/rlp/test_via_rlp.py
--ignore=src/pytest_plugins/consume/simulators/
--ignore=src/pytest_plugins/consume/simulators/engine/test_via_engine.py
--ignore=src/pytest_plugins/consume/simulators/rlp/test_via_rlp.py
--ignore=src/pytest_plugins/execute/test_recover.py
2 changes: 1 addition & 1 deletion src/cli/extract_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from ethereum_test_fixtures.file import Fixtures
from ethereum_test_fixtures.pre_alloc_groups import PreAllocGroup
from ethereum_test_forks import Fork
from pytest_plugins.consume.hive_simulators.ruleset import ruleset
from pytest_plugins.consume.simulators.helpers.ruleset import ruleset


def get_docker_containers() -> set[str]:
Expand Down
58 changes: 47 additions & 11 deletions src/cli/pytest_commands/consume.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
class ConsumeCommand(PytestCommand):
"""Pytest command for consume operations."""

def __init__(self, command_paths: List[Path], is_hive: bool = False):
def __init__(self, command_paths: List[Path], is_hive: bool = False, command_name: str = ""):
"""Initialize consume command with paths and processors."""
processors: List[ArgumentProcessor] = [HelpFlagsProcessor("consume")]

if is_hive:
processors.extend(
[
HiveEnvironmentProcessor(),
HiveEnvironmentProcessor(command_name=command_name),
ConsumeCommandProcessor(is_hive=True),
]
)
Expand Down Expand Up @@ -54,13 +54,17 @@ def get_command_paths(command_name: str, is_hive: bool) -> List[Path]:
base_path = Path("src/pytest_plugins/consume")
if command_name == "hive":
commands = ["rlp", "engine"]
command_paths = [
base_path / "simulators" / "hive_tests" / f"test_via_{cmd}.py" for cmd in commands
]
elif command_name in ["engine", "enginex"]:
command_paths = [base_path / "simulators" / "hive_tests" / "test_via_engine.py"]
elif command_name == "rlp":
command_paths = [base_path / "simulators" / "hive_tests" / "test_via_rlp.py"]
elif command_name == "direct":
command_paths = [base_path / "direct" / "test_via_direct.py"]
else:
commands = [command_name]

command_paths = [
base_path / ("hive_simulators" if is_hive else "") / cmd / f"test_via_{cmd}.py"
for cmd in commands
]
raise ValueError(f"Unexpected command: {command_name}.")
return command_paths


Expand All @@ -86,7 +90,7 @@ def decorator(func: Callable[..., Any]) -> click.Command:
@common_pytest_options
@functools.wraps(func)
def command(pytest_args: List[str], **kwargs) -> None:
consume_cmd = ConsumeCommand(command_paths, is_hive)
consume_cmd = ConsumeCommand(command_paths, is_hive, command_name)
consume_cmd.execute(list(pytest_args))

return command
Expand All @@ -108,13 +112,45 @@ def rlp() -> None:

@consume_command(is_hive=True)
def engine() -> None:
"""Client consumes via the Engine API."""
"""Client consumes Engine Fixtures via the Engine API."""
pass


@consume.command(
name="enginex",
help="Client consumes Engine X Fixtures via the Engine API.",
context_settings={"ignore_unknown_options": True},
)
@click.option(
"--enginex-fcu-frequency",
type=int,
default=1,
help=(
"Control forkchoice update frequency for enginex simulator. "
"0=disable FCUs, 1=FCU every test (default), N=FCU every Nth test per "
"pre-allocation group."
),
)
@common_pytest_options
def enginex(enginex_fcu_frequency: int, pytest_args: List[str], **_kwargs) -> None:
"""Client consumes Engine X Fixtures via the Engine API."""
command_name = "enginex"
command_paths = get_command_paths(command_name, is_hive=True)

# Validate the frequency parameter
if enginex_fcu_frequency < 0:
raise click.BadParameter("FCU frequency must be non-negative")

# Add the FCU frequency to pytest args as a custom config option
pytest_args_with_fcu = [f"--enginex-fcu-frequency={enginex_fcu_frequency}"] + list(pytest_args)

consume_cmd = ConsumeCommand(command_paths, is_hive=True, command_name=command_name)
consume_cmd.execute(pytest_args_with_fcu)


@consume_command(is_hive=True)
def hive() -> None:
"""Client consumes via all available hive methods (rlp, engine)."""
"""Client consumes via rlp & engine hive methods."""
pass


Expand Down
20 changes: 18 additions & 2 deletions src/cli/pytest_commands/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ def _is_writing_to_stdout(self, args: List[str]) -> bool:
class HiveEnvironmentProcessor(ArgumentProcessor):
"""Processes Hive environment variables for consume commands."""

def __init__(self, command_name: str):
"""
Initialize the processor with command name to determine plugin.

Args:
command_name: The command name to determine which plugin to load.

"""
self.command_name = command_name

def process_args(self, args: List[str]) -> List[str]:
"""Convert hive environment variables into pytest flags."""
modified_args = args[:]
Expand All @@ -92,8 +102,14 @@ def process_args(self, args: List[str]) -> List[str]:
if os.getenv("HIVE_LOGLEVEL") is not None:
warnings.warn("HIVE_LOG_LEVEL is not yet supported.", stacklevel=2)

modified_args.extend(["-p", "pytest_plugins.pytest_hive.pytest_hive"])

if self.command_name == "engine":
modified_args.extend(["-p", "pytest_plugins.consume.simulators.engine.conftest"])
elif self.command_name == "enginex":
modified_args.extend(["-p", "pytest_plugins.consume.simulators.enginex.conftest"])
elif self.command_name == "rlp":
modified_args.extend(["-p", "pytest_plugins.consume.simulators.rlp.conftest"])
else:
raise ValueError(f"Unknown command name: {self.command_name}")
return modified_args

def _has_regex_or_sim_limit(self, args: List[str]) -> bool:
Expand Down
Loading
Loading