feat(consume): initial implementation of enginex#1
feat(consume): initial implementation of enginex#1danceratopz wants to merge 4 commits intoconsume-enginexfrom
Conversation
danceratopz
left a comment
There was a problem hiding this comment.
More xdist code landed in this PR than intended. Indeed, this should run correctly with xdist if loadgroup is provided to xdist's distribution flag:
-n 8 --dist=loadgroupThe xdist_group test markers, which set the xdist group to be the test's pre-alloc group hash, provide an elegant way of keeping track of test execution, so I decided to leave them in this initial PR. The purpose of these markers in xdist is to enforce that one group (which is equivalent to execution on one client, in this PR) is distributed to the same worker, not amongst multiple workers. It could even work without (if no fcu is applied), but this approach feels safest/more optimal with regards to loading resources (e.g., genesis, env).
The caching of genesis, env,.. is not necessary until we perform further optimizations, but I don't think it's too confusing if the reviewer bears in mind what's coming: We will enforce a max-group size on the pre-alloc groups and further divide them based on that parameter. This allows for better distribution of (our very skewed group distribution; some very large, many very small) groups across workers, which helps avoid worker starvation.
| f"BlockchainEngineXFixture test case '{test_case.id}' missing pre_hash" | ||
| ) | ||
| group_identifier = test_case.pre_hash | ||
| marks.append(pytest.mark.xdist_group(name=group_identifier)) |
There was a problem hiding this comment.
We add this xdist-specific marker now, even in sequential mode, as it's an elegant solution to help track the count of tests pending/executed in each pre-alloc group (in order to terminate the client upon completion of all collected tests in the group).
There was a problem hiding this comment.
Update: This PR now contains basic, unoptimized xdist support.
...ting/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/engine/conftest.py
Outdated
Show resolved
Hide resolved
...ting/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/engine/conftest.py
Outdated
Show resolved
Hide resolved
| @pytest.fixture(scope="session") | ||
| def pre_alloc_group_cache() -> Dict[str, PreAllocGroup]: | ||
| """Cache for pre-allocation groups to avoid reloading from disk.""" | ||
| return {} | ||
|
|
||
|
|
||
| @pytest.fixture(scope="session") | ||
| def client_genesis_cache() -> Dict[str, dict]: | ||
| """Cache for client genesis configs to avoid redundant to_json calls.""" | ||
| return {} | ||
|
|
||
|
|
||
| @pytest.fixture(scope="session") | ||
| def environment_cache() -> Dict[str, dict]: | ||
| """Cache for environment configs to avoid redundant computation.""" | ||
| return {} |
There was a problem hiding this comment.
Ah, these snuck in here, these caches are not necessary in sequential mode, where each pre-alloc group only gets executed once.
This caching is actually only useful when splitting large pre-alloc groups into smaller ones (we do this in xdist mode to allow better distribution of groups amongst workers and avoid worker starvation).
be91a38 to
479d579
Compare
479d579 to
e47a3cc
Compare
…m#1666) * refactor(tests): Refactor json_infra using `pytest_collect_file` * fix(tests): json collecting * fix(tests): blockchain test execution * fix(tests): blockchain test execution * refactor(tests): Refactor types in json_infra * fix(tests): json_infra, imports, parse `exceptions` in some tests * refactor(tests): move some definitions * fix(tox.ini): Remove `--ignore-glob` * fix(tests): workaround for FileNotFoundError * fix(tests): revamp cache fix(tests): Don't cache fixtures Try to implement cache Fix caching feat(tests): Manage cache during execution * fix(tox): Use `--dist=loadfile` * fix(tests): json files cache * Run selective tests based on changed files (#1) * fix(tests): remove evm_tools marker from blockchain tests * remove coverage from json_infra * enhance(tools): add json_test_name to Hardfork * fix(tests): handle failing transactions in state tests * enhance(tests): add from and until fork option to json_infra * enhance(tests): run json_infra selectively * enhance(tests): subclass Hardfork * bug(tests): run all tests for t8n changes * enhance(tests): minor fix * fix(tests): ignore expectSection tests and add coverage * enhance(tests): refactor exception markers This commit refactors exception markers and marks the EEST static tests as slow * fix(tests): provide unique name to tests * fix(tests): post review changes * fix(tests): set BASE_SHA to merge base --------- Co-authored-by: Guruprasad Kamath <48196632+gurukamath@users.noreply.github.com> Co-authored-by: Guruprasad Kamath <guru241987@gmail.com>
…saka-suggestions fix(test-benchmark): update gas constants in calculations and comments
🗒️ Description
This PR adds an initial implementation of a
consume enginexsimulator that reuses client instances across tests sharing the same pre-allocation state to optimize test execution.This PR does have basic
pytest-xdistsupport which will be optimized in subsequent PRs.Pending optimization: A huge performance gain is made if this PR is rebased on @marioevz's "optimize fill" PR ethereum#1804. For example, this command of 20 tests over two groups runs ~3x faster:
This is because as-is, the genesis state root is (unnecessarily) calculated for every access of the pre-alloc group.
Note on fixtures:
--until Prague(no static tests).slow, which reduces the number of pre-alloc groups from 23938 to 312. This change will be PR'd independently. You can get this group information from the release, for example, via:Overview
The
enginexsimulator groups tests bypre_hash(hash of genesis + pre-state). Tests in the same group run against a single client instance instead of starting/stopping per test.Key Components
New Files
simulators/enginex/conftest.py- Client fixture with reuse logic, test sorting by groupsimulators/multi_test_client.py-MultiTestClientManagerfor client lifecycle, parallel fixtures tosingle_test_client.pysimulators/helpers/test_tracker.py- Tracks test completion per group for cleanupfixtures/pre_alloc_groups.py-PreAllocGroupmodel for shared genesis/pre-stateModified
consume.py- Addsxdist_groupmarker based onpre_hashfor enginex fixturestest_via_engine.py- Shared test logic betweenengineandenginexpytest_hive.py-shared_hive_testfixture for cross-test client sharingFlow
pytest_collection_modifyitemscounts tests per group, sorts bypre_hashmark_test_completedtriggers client shutdownFixture Chain
Usage
To test, you can use the recommended bootleg release here: https://github.com/danceratopz/execution-specs/releases/tag/v0.1.0a1
uv run consume enginex --input=https://github.com/danceratopz/execution-specs/releases/download/v0.1.0a1/fixtures.tar.gz -v -s -k "/shanghai/ and (fork_shanghai or fork_cancun) and push0"🔗 Related Issues or PRs
N/A.
✅ Checklist
toxchecks to avoid unnecessary CI fails, see also Code Standards and Enabling Pre-commit Checks:uvx tox -e statictype(scope):.All: Considered adding an entry to CHANGELOG.md. skipped