From 4ccfc8a920d7bceaefb79db2cbe2d1aa3a42e358 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Fri, 28 Nov 2025 16:40:14 +0100 Subject: [PATCH 1/4] enhance(tests): select ethash tests based on fork --- tests/json_infra/test_ethash.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/json_infra/test_ethash.py b/tests/json_infra/test_ethash.py index ec2368083c..e12ae035d1 100644 --- a/tests/json_infra/test_ethash.py +++ b/tests/json_infra/test_ethash.py @@ -26,6 +26,7 @@ from . import FORKS, TEST_FIXTURES from .helpers.load_blockchain_tests import Load +from .stash_keys import desired_forks_key ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] @@ -41,9 +42,16 @@ ] +@pytest.mark.slow @pytest.mark.parametrize("json_fork", POW_FORKS) -def test_ethtest_fixtures(json_fork: str) -> None: +def test_ethtest_fixtures( + json_fork: str, request: pytest.FixtureRequest +) -> None: """Tests ethash proof-of-work validation against ethereum test fixtures.""" + desired_forks = request.config.stash.get(desired_forks_key, []) + if json_fork not in desired_forks: + pytest.skip(f"Fork {json_fork} not in desired forks") + eels_fork = FORKS[json_fork].short_name fork_module = importlib.import_module(f"ethereum.forks.{eels_fork}.fork") @@ -116,12 +124,16 @@ def load_pow_test_fixtures(json_fork: str) -> List[Dict[str, Any]]: ], ) def test_pow_validation_block_headers( - json_fork: str, block_file_name: str + json_fork: str, block_file_name: str, request: pytest.FixtureRequest ) -> None: """ Tests proof-of-work validation on real block headers for specific forks. """ + desired_forks = request.config.stash.get(desired_forks_key, []) + if json_fork not in desired_forks: + pytest.skip(f"Fork {json_fork} not in desired forks") + eels_fork = FORKS[json_fork].short_name fork_module = importlib.import_module(f"ethereum.forks.{eels_fork}.fork") From 4d07a1f9adbcf8c525b315c6eea9196a1a8174a7 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Fri, 28 Nov 2025 16:47:06 +0100 Subject: [PATCH 2/4] enhance(tests): select trie tests based on fork --- tests/json_infra/test_trie.py | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/tests/json_infra/test_trie.py b/tests/json_infra/test_trie.py index e950fbf486..445736f3b3 100644 --- a/tests/json_infra/test_trie.py +++ b/tests/json_infra/test_trie.py @@ -10,6 +10,7 @@ from ethereum.utils.hexadecimal import has_hex_prefix, hex_to_bytes from . import FORKS, TEST_FIXTURES +from .stash_keys import desired_forks_key FIXTURE_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] @@ -27,8 +28,12 @@ def to_bytes(data: Optional[str]) -> Bytes: @pytest.mark.parametrize("fork", forks) -def test_trie_secure_hex(fork: str) -> None: +def test_trie_secure_hex(fork: str, request: pytest.FixtureRequest) -> None: """Tests secure trie implementation with hex-encoded test data.""" + desired_forks = request.config.stash.get(desired_forks_key, []) + if fork not in desired_forks: + pytest.skip(f"Fork {fork} not in desired forks") + tests = load_tests("hex_encoded_securetrie_test.json") eels_fork = FORKS[fork].short_name @@ -44,8 +49,12 @@ def test_trie_secure_hex(fork: str) -> None: @pytest.mark.parametrize("fork", forks) -def test_trie_secure(fork: str) -> None: +def test_trie_secure(fork: str, request: pytest.FixtureRequest) -> None: """Tests secure trie implementation with standard test data.""" + desired_forks = request.config.stash.get(desired_forks_key, []) + if fork not in desired_forks: + pytest.skip(f"Fork {fork} not in desired forks") + tests = load_tests("trietest_secureTrie.json") eels_fork = FORKS[fork].short_name @@ -61,8 +70,14 @@ def test_trie_secure(fork: str) -> None: @pytest.mark.parametrize("fork", forks) -def test_trie_secure_any_order(fork: str) -> None: +def test_trie_secure_any_order( + fork: str, request: pytest.FixtureRequest +) -> None: """Tests secure trie implementation with any-order test data.""" + desired_forks = request.config.stash.get(desired_forks_key, []) + if fork not in desired_forks: + pytest.skip(f"Fork {fork} not in desired forks") + tests = load_tests("trieanyorder_secureTrie.json") eels_fork = FORKS[fork].short_name @@ -78,8 +93,12 @@ def test_trie_secure_any_order(fork: str) -> None: @pytest.mark.parametrize("fork", forks) -def test_trie(fork: str) -> None: +def test_trie(fork: str, request: pytest.FixtureRequest) -> None: """Tests non-secure trie implementation with standard test data.""" + desired_forks = request.config.stash.get(desired_forks_key, []) + if fork not in desired_forks: + pytest.skip(f"Fork {fork} not in desired forks") + tests = load_tests("trietest.json") eels_fork = FORKS[fork].short_name @@ -95,8 +114,12 @@ def test_trie(fork: str) -> None: @pytest.mark.parametrize("fork", forks) -def test_trie_any_order(fork: str) -> None: +def test_trie_any_order(fork: str, request: pytest.FixtureRequest) -> None: """Tests non-secure trie implementation with any-order test data.""" + desired_forks = request.config.stash.get(desired_forks_key, []) + if fork not in desired_forks: + pytest.skip(f"Fork {fork} not in desired forks") + tests = load_tests("trieanyorder.json") eels_fork = FORKS[fork].short_name From 869e1bd516ea3add875d91532bc494780732e336 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Fri, 28 Nov 2025 18:38:04 +0100 Subject: [PATCH 3/4] enhance(tests): align vm tests with state and block tests --- tests/json_infra/helpers/__init__.py | 2 + .../helpers/exceptional_test_patterns.py | 21 ++ tests/json_infra/helpers/load_vm_tests.py | 184 ++++++++-- tests/json_infra/vm/__init__.py | 13 - .../vm/test_arithmetic_operations.py | 335 ------------------ .../vm/test_bitwise_logic_operations.py | 208 ----------- tests/json_infra/vm/test_block_operations.py | 49 --- .../vm/test_control_flow_operations.py | 213 ----------- .../vm/test_environmental_operations.py | 138 -------- tests/json_infra/vm/test_keccak.py | 58 --- .../json_infra/vm/test_logging_operations.py | 119 ------- tests/json_infra/vm/test_memory_operations.py | 91 ----- tests/json_infra/vm/test_stack_operations.py | 131 ------- .../json_infra/vm/test_storage_operations.py | 36 -- tests/json_infra/vm/test_system_operations.py | 61 ---- 15 files changed, 187 insertions(+), 1472 deletions(-) delete mode 100644 tests/json_infra/vm/__init__.py delete mode 100644 tests/json_infra/vm/test_arithmetic_operations.py delete mode 100644 tests/json_infra/vm/test_bitwise_logic_operations.py delete mode 100644 tests/json_infra/vm/test_block_operations.py delete mode 100644 tests/json_infra/vm/test_control_flow_operations.py delete mode 100644 tests/json_infra/vm/test_environmental_operations.py delete mode 100644 tests/json_infra/vm/test_keccak.py delete mode 100644 tests/json_infra/vm/test_logging_operations.py delete mode 100644 tests/json_infra/vm/test_memory_operations.py delete mode 100644 tests/json_infra/vm/test_stack_operations.py delete mode 100644 tests/json_infra/vm/test_storage_operations.py delete mode 100644 tests/json_infra/vm/test_system_operations.py diff --git a/tests/json_infra/helpers/__init__.py b/tests/json_infra/helpers/__init__.py index 2980c854e2..ad9917bbf5 100644 --- a/tests/json_infra/helpers/__init__.py +++ b/tests/json_infra/helpers/__init__.py @@ -3,8 +3,10 @@ from .fixtures import ALL_FIXTURE_TYPES, Fixture, FixturesFile, FixtureTestItem from .load_blockchain_tests import BlockchainTestFixture from .load_state_tests import StateTestFixture +from .load_vm_tests import VmTestFixture ALL_FIXTURE_TYPES.append(BlockchainTestFixture) ALL_FIXTURE_TYPES.append(StateTestFixture) +ALL_FIXTURE_TYPES.append(VmTestFixture) __all__ = ["ALL_FIXTURE_TYPES", "Fixture", "FixturesFile", "FixtureTestItem"] diff --git a/tests/json_infra/helpers/exceptional_test_patterns.py b/tests/json_infra/helpers/exceptional_test_patterns.py index 658f32d581..a1ee995227 100644 --- a/tests/json_infra/helpers/exceptional_test_patterns.py +++ b/tests/json_infra/helpers/exceptional_test_patterns.py @@ -140,3 +140,24 @@ def exceptional_state_test_patterns( expected_fail=tuple(), big_memory=tuple(), ) + + +def exceptional_vm_test_patterns( + json_fork: str, eels_fork: str +) -> TestPatterns: + """ + Returns patterns for slow, ignored, and big-memory VM tests for a + given json_fork and eels_fork. + """ + del json_fork, eels_fork # Not used for VM tests currently + + slow_tests = ( + # vmPerformance tests are slow + "vmPerformance/", + ) + + return TestPatterns( + slow=tuple(re.compile(p) for p in slow_tests), + expected_fail=tuple(), + big_memory=tuple(), + ) diff --git a/tests/json_infra/helpers/load_vm_tests.py b/tests/json_infra/helpers/load_vm_tests.py index 843ec4cb5a..b06d5bd300 100644 --- a/tests/json_infra/helpers/load_vm_tests.py +++ b/tests/json_infra/helpers/load_vm_tests.py @@ -1,12 +1,15 @@ """Helper class to load and run VM tests.""" -import json -import os from importlib import import_module -from typing import Any, List +from pathlib import Path +from typing import Any, Dict, Generator, List, Tuple +import pytest +from _pytest.config import Config +from _pytest.nodes import Item from ethereum_rlp import rlp from ethereum_types.numeric import U64, U256, Uint +from pytest import Collector from ethereum.crypto.hash import keccak256 from ethereum.utils.hexadecimal import ( @@ -16,6 +19,27 @@ hex_to_uint, ) +from ..hardfork import TestHardfork +from ..stash_keys import desired_forks_key +from .exceptional_test_patterns import exceptional_vm_test_patterns +from .fixtures import Fixture, FixturesFile, FixtureTestItem + + +def _get_vm_forks() -> List[TestHardfork]: + """ + Get the list of forks for which VM tests should run. + + VM tests are only run for legacy forks up to Constantinople. + """ + all_forks = list(TestHardfork.discover()) + constantinople = next( + f for f in all_forks if f.short_name == "constantinople" + ) + return [f for f in all_forks if f.criteria <= constantinople.criteria] + + +VM_FORKS: List[TestHardfork] = _get_vm_forks() + class VmTestLoader: """ @@ -61,13 +85,11 @@ def __init__(self, network: str, fork_name: str): def _module(self, name: str) -> Any: return import_module(f"ethereum.forks.{self.fork_name}.{name}") - def run_test( - self, test_dir: str, test_file: str, check_gas_left: bool = True - ) -> None: + def run_test_from_dict(self, json_data: Dict[str, Any]) -> None: """ - Execute a test case and check its post state. + Execute a test case from parsed JSON data and check its post state. """ - test_data = self.load_test(test_dir, test_file) + test_data = self.prepare_test_data(json_data) block_env = test_data["block_env"] tx_env = test_data["tx_env"] tx = test_data["tx"] @@ -81,8 +103,6 @@ def run_test( output = self.process_message_call(message) if test_data["has_post_state"]: - if check_gas_left: - assert output.gas_left == test_data["expected_gas_left"] assert ( keccak256(rlp.encode(output.logs)) == test_data["expected_logs_hash"] @@ -101,15 +121,10 @@ def run_test( self.close_state(block_env.state) self.close_state(test_data["expected_post_state"]) - def load_test(self, test_dir: str, test_file: str) -> Any: + def prepare_test_data(self, json_data: Dict[str, Any]) -> Dict[str, Any]: """ - Read tests from a file. + Prepare test data from parsed JSON. """ - test_name = os.path.splitext(test_file)[0] - path = os.path.join(test_dir, test_file) - with open(path, "r") as fp: - json_data = json.load(fp)[test_name] - block_env = self.json_to_block_env(json_data) tx = self.Transaction( @@ -156,9 +171,8 @@ def json_to_block_env(self, json_data: Any) -> Any: # Hence creating a dummy caller state. if caller_hex_address not in json_data["pre"]: value = json_data["exec"]["value"] - json_data["pre"][caller_hex_address] = ( - self.get_dummy_account_state(value) - ) + dummy_state = self.get_dummy_account_state(value) + json_data["pre"][caller_hex_address] = dummy_state current_state = self.json_to_state(json_data["pre"]) @@ -226,3 +240,133 @@ def get_dummy_account_state(self, min_balance: str) -> Any: "nonce": "0x00", "storage": {}, } + + +class VmTest(FixtureTestItem): + """Single VM test case item for a specific fork.""" + + fork_name: str + eels_fork: str + + def __init__( + self, + *args: Any, + fork_name: str, + eels_fork: str, + **kwargs: Any, + ) -> None: + """Initialize a single VM test case item.""" + super().__init__(*args, **kwargs) + self.fork_name = fork_name + self.eels_fork = eels_fork + self.add_marker(pytest.mark.fork(self.fork_name)) + self.add_marker("vm_test") + + # Mark tests with exceptional markers + test_patterns = exceptional_vm_test_patterns(fork_name, eels_fork) + if any(x.search(self.nodeid) for x in test_patterns.slow): + self.add_marker("slow") + + @property + def vm_test_fixture(self) -> "VmTestFixture": + """Return the VM test fixture this test belongs to.""" + parent = self.parent + assert parent is not None + assert isinstance(parent, VmTestFixture) + return parent + + @property + def test_key(self) -> str: + """Return the key of the VM test fixture in the fixture file.""" + return self.vm_test_fixture.test_key + + @property + def fixtures_file(self) -> FixturesFile: + """Fixtures file from which the test fixture was collected.""" + return self.vm_test_fixture.fixtures_file + + @property + def test_dict(self) -> Dict[str, Any]: + """Load test from disk.""" + loaded_file = self.fixtures_file.data + return loaded_file[self.test_key] + + def runtest(self) -> None: + """Run a VM test from JSON test case data.""" + loader = VmTestLoader(self.fork_name, self.eels_fork) + loader.run_test_from_dict(self.test_dict) + + def reportinfo(self) -> Tuple[Path, int, str]: + """Return information for test reporting.""" + return self.path, 1, self.name + + +class VmTestFixture(Fixture, Collector): + """ + VM test fixture from a JSON file that yields test items for each + supported fork. + """ + + @classmethod + def is_format(cls, test_dict: Dict[str, Any]) -> bool: + """Return true if the object can be parsed as a VM test fixture.""" + # VM tests have exec, env, and pre keys + if "exec" not in test_dict: + return False + if "env" not in test_dict: + return False + if "pre" not in test_dict: + return False + if "logs" not in test_dict: + return False + # Make sure it's not a state test (which has "transaction" and "post") + if "transaction" in test_dict: + return False + return True + + @property + def fixtures_file(self) -> FixturesFile: + """Fixtures file from which the test fixture was collected.""" + parent = self.parent + assert parent is not None + assert isinstance(parent, FixturesFile) + return parent + + @property + def test_dict(self) -> Dict[str, Any]: + """Load test from disk.""" + loaded_file = self.fixtures_file.data + return loaded_file[self.test_key] + + def collect(self) -> Generator[Item | Collector, None, None]: + """Collect VM test cases for each supported fork.""" + desired_forks: List[str] = self.config.stash.get(desired_forks_key, []) + + for fork in VM_FORKS: + if fork.json_test_name not in desired_forks: + continue + yield VmTest.from_parent( + parent=self, + name=fork.json_test_name, + fork_name=fork.json_test_name, + eels_fork=fork.short_name, + ) + + @classmethod + def has_desired_fork( + cls, + test_dict: Dict[str, Any], # noqa: ARG003 + config: Config, + ) -> bool: + """ + Check if any of the VM test forks are in the desired forks list. + """ + desired_forks = config.stash.get(desired_forks_key, None) + if desired_forks is None: + return True + + # Check if any VM fork is in the desired forks + for fork in VM_FORKS: + if fork.json_test_name in desired_forks: + return True + return False diff --git a/tests/json_infra/vm/__init__.py b/tests/json_infra/vm/__init__.py deleted file mode 100644 index 07b87bed4c..0000000000 --- a/tests/json_infra/vm/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -VM tests forks configuration. -These tests are only run for legacy forks up to Constantinople. -""" - -FORKS = [ - ("ConstantinopleFix", "constantinople"), - ("Byzantium", "byzantium"), - ("EIP158", "spurious_dragon"), - ("EIP150", "tangerine_whistle"), - ("Homestead", "homestead"), - ("Frontier", "frontier"), -] diff --git a/tests/json_infra/vm/test_arithmetic_operations.py b/tests/json_infra/vm/test_arithmetic_operations.py deleted file mode 100644 index 976f8222ee..0000000000 --- a/tests/json_infra/vm/test_arithmetic_operations.py +++ /dev/null @@ -1,335 +0,0 @@ -"""Tests for arithmetic operations in the EVM.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmArithmeticTest" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "add0.json", - "add1.json", - "add2.json", - "add3.json", - "add4.json", - ], -) -def test_add(fork: Tuple[str, str], test_file: str) -> None: - """Tests ADD operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "sub0.json", - "sub1.json", - "sub2.json", - "sub3.json", - "sub4.json", - ], -) -def test_sub(fork: Tuple[str, str], test_file: str) -> None: - """Tests SUB operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "mul0.json", - "mul1.json", - "mul2.json", - "mul3.json", - "mul4.json", - "mul5.json", - "mul6.json", - "mul7.json", - ], -) -def test_mul(fork: Tuple[str, str], test_file: str) -> None: - """Tests MUL operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "div1.json", - "divBoostBug.json", - "divByNonZero0.json", - "divByNonZero1.json", - "divByNonZero2.json", - "divByNonZero3.json", - "divByZero.json", - "divByZero_2.json", - ], -) -def test_div(fork: Tuple[str, str], test_file: str) -> None: - """Tests DIV operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "sdiv0.json", - "sdiv1.json", - "sdiv2.json", - "sdiv3.json", - "sdiv4.json", - "sdiv5.json", - "sdiv6.json", - "sdiv7.json", - "sdiv8.json", - "sdiv9.json", - "sdivByZero0.json", - "sdivByZero1.json", - "sdivByZero2.json", - "sdiv_i256min.json", - "sdiv_i256min2.json", - "sdiv_i256min3.json", - "sdiv_dejavu.json", - ], -) -def test_sdiv(fork: Tuple[str, str], test_file: str) -> None: - """Tests SDIV operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "mod0.json", - "mod1.json", - "mod2.json", - "mod3.json", - "mod4.json", - "modByZero.json", - ], -) -def test_mod(fork: Tuple[str, str], test_file: str) -> None: - """Tests MOD operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "smod0.json", - "smod1.json", - "smod2.json", - "smod3.json", - "smod4.json", - "smod5.json", - "smod6.json", - "smod7.json", - "smod8_byZero.json", - "smod_i256min1.json", - "smod_i256min2.json", - ], -) -def test_smod(fork: Tuple[str, str], test_file: str) -> None: - """Tests SMOD operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "addmod0.json", - "addmod1.json", - "addmod1_overflow2.json", - "addmod1_overflow3.json", - "addmod1_overflow4.json", - "addmod1_overflowDiff.json", - "addmod2.json", - "addmod2_0.json", - "addmod2_1.json", - "addmod3.json", - "addmod3_0.json", - ], -) -def test_addmod(fork: Tuple[str, str], test_file: str) -> None: - """Tests ADDMOD operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "mulmod0.json", - "mulmod1.json", - "mulmod1_overflow.json", - "mulmod1_overflow2.json", - "mulmod1_overflow3.json", - "mulmod1_overflow4.json", - "mulmod2.json", - "mulmod2_0.json", - "mulmod2_1.json", - "mulmod3.json", - "mulmod3_0.json", - "mulmod4.json", - ], -) -def test_mulmod(fork: Tuple[str, str], test_file: str) -> None: - """Tests MULMOD operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "exp0.json", - "exp1.json", - "exp2.json", - "exp3.json", - "exp4.json", - "exp5.json", - "exp6.json", - "exp7.json", - "exp8.json", - "expXY.json", - "expXY_success.json", - ], -) -def test_exp(fork: Tuple[str, str], test_file: str) -> None: - """Tests EXP operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - check_gas_left=False, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize("exponent", ([2, 4, 8, 16, 32, 64, 128, 256])) -def test_exp_power_2(fork: Tuple[str, str], exponent: int) -> None: - """ - Tests EXP operations with powers of 2 exponents using VM - test fixtures. - """ - VmTestLoader(*fork).run_test( - TEST_DIR, - f"expPowerOf2_{exponent}.json", - check_gas_left=False, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_exp_power_256(fork: Tuple[str, str]) -> None: - """ - Tests EXP operations with power of 256 exponent using VM - test fixtures. - """ - for i in range(1, 34): - VmTestLoader(*fork).run_test( - TEST_DIR, - f"expPowerOf256_{i}.json", - check_gas_left=False, - ) - - for i in range(34): - VmTestLoader(*fork).run_test( - TEST_DIR, - f"expPowerOf256Of256_{i}.json", - check_gas_left=False, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "signextend_0_BigByte.json", - "signextend_00.json", - "signextend_AlmostBiggestByte.json", - "signextend_BigByte_0.json", - "signextend_BigByteBigByte.json", - "signextend_BigBytePlus1_2.json", - "signextend_bigBytePlus1.json", - "signextend_BitIsNotSet.json", - "signextend_BitIsNotSetInHigherByte.json", - "signextend_bitIsSet.json", - "signextend_BitIsSetInHigherByte.json", - "signextend_Overflow_dj42.json", - "signextendInvalidByteNumber.json", - ], -) -def test_signextend(fork: Tuple[str, str], test_file: str) -> None: - """Tests SIGNEXTEND operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - test_file, - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_stop(fork: Tuple[str, str]) -> None: - """Tests STOP operation using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, - "stop.json", - ) diff --git a/tests/json_infra/vm/test_bitwise_logic_operations.py b/tests/json_infra/vm/test_bitwise_logic_operations.py deleted file mode 100644 index 6703e145aa..0000000000 --- a/tests/json_infra/vm/test_bitwise_logic_operations.py +++ /dev/null @@ -1,208 +0,0 @@ -"""Tests for bitwise and logic operations.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmBitwiseLogicOperation" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "lt0.json", - "lt1.json", - "lt2.json", - "lt3.json", - ], -) -def test_lt(fork: Tuple[str, str], test_file: str) -> None: - """Tests LT operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "gt0.json", - "gt1.json", - "gt2.json", - "gt3.json", - ], -) -def test_gt(fork: Tuple[str, str], test_file: str) -> None: - """Tests GT operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "slt0.json", - "slt1.json", - "slt2.json", - "slt3.json", - "slt4.json", - ], -) -def test_slt(fork: Tuple[str, str], test_file: str) -> None: - """Tests SLT operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "sgt0.json", - "sgt1.json", - "sgt2.json", - "sgt3.json", - "sgt4.json", - ], -) -def test_sgt(fork: Tuple[str, str], test_file: str) -> None: - """Tests SGT operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "eq0.json", - "eq1.json", - "eq2.json", - ], -) -def test_eq(fork: Tuple[str, str], test_file: str) -> None: - """Tests EQ operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "iszero0.json", - "iszero1.json", - "iszeo2.json", - ], -) -def test_iszero(fork: Tuple[str, str], test_file: str) -> None: - """Tests ISZERO operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "and0.json", - "and1.json", - "and2.json", - "and3.json", - "and4.json", - "and5.json", - ], -) -def test_and(fork: Tuple[str, str], test_file: str) -> None: - """Tests AND operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "or0.json", - "or1.json", - "or2.json", - "or3.json", - "or4.json", - "or5.json", - ], -) -def test_or(fork: Tuple[str, str], test_file: str) -> None: - """Tests OR operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "xor0.json", - "xor1.json", - "xor2.json", - "xor3.json", - "xor4.json", - "xor5.json", - ], -) -def test_xor(fork: Tuple[str, str], test_file: str) -> None: - """Tests XOR operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "not0.json", - "not1.json", - "not2.json", - "not3.json", - "not4.json", - "not5.json", - ], -) -def test_not(fork: Tuple[str, str], test_file: str) -> None: - """Tests NOT operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "byte0.json", - "byte1.json", - "byte2.json", - "byte3.json", - "byte4.json", - "byte5.json", - "byte6.json", - "byte7.json", - "byte8.json", - "byte9.json", - "byte10.json", - "byte11.json", - "byteBN.json", - ], -) -def test_byte(fork: Tuple[str, str], test_file: str) -> None: - """Tests BYTE operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) diff --git a/tests/json_infra/vm/test_block_operations.py b/tests/json_infra/vm/test_block_operations.py deleted file mode 100644 index 88816f6057..0000000000 --- a/tests/json_infra/vm/test_block_operations.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Tests for block operations.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/vmBlockInfoTest" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_coinbase(fork: Tuple[str, str]) -> None: - """Tests COINBASE operation using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "coinbase.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_timestamp(fork: Tuple[str, str]) -> None: - """Tests TIMESTAMP operation using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "timestamp.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_number(fork: Tuple[str, str]) -> None: - """Tests NUMBER operation using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "number.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_difficulty(fork: Tuple[str, str]) -> None: - """Tests DIFFICULTY operation using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "difficulty.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_gas_limit(fork: Tuple[str, str]) -> None: - """Tests GASLIMIT operation using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "gaslimit.json") diff --git a/tests/json_infra/vm/test_control_flow_operations.py b/tests/json_infra/vm/test_control_flow_operations.py deleted file mode 100644 index f04c92a00b..0000000000 --- a/tests/json_infra/vm/test_control_flow_operations.py +++ /dev/null @@ -1,213 +0,0 @@ -"""Tests for EVM control flow operations.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmIOandFlowOperations" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file, check_gas_left", - [ - ("jump0_jumpdest0.json", True), - ("jump0_jumpdest2.json", True), - ("jumpAfterStop.json", True), - ("jumpdestBigList.json", True), - ("jumpTo1InstructionafterJump.json", True), - ("jumpDynamicJumpSameDest.json", True), - ("indirect_jump1.json", True), - ("indirect_jump2.json", True), - ("indirect_jump3.json", True), - ("DynamicJump_value1.json", True), - ("DynamicJump_value2.json", True), - ("DynamicJump_value3.json", True), - ("stackjump1.json", True), - ("indirect_jump4.json", True), - ("JDfromStorageDynamicJump0_jumpdest0.json", False), - ("JDfromStorageDynamicJump0_jumpdest2.json", False), - ("DynamicJump0_jumpdest0.json", True), - ("DynamicJump0_jumpdest2.json", True), - ("DynamicJumpAfterStop.json", True), - ("DynamicJumpJD_DependsOnJumps1.json", True), - ("DynamicJumpPathologicalTest0.json", True), - ("DynamicJumpStartWithJumpDest.json", True), - ("BlockNumberDynamicJump0_jumpdest0.json", True), - ("BlockNumberDynamicJump0_jumpdest2.json", True), - ("bad_indirect_jump1.json", True), - ("bad_indirect_jump2.json", True), - ("jump0_AfterJumpdest.json", True), - ("jump0_AfterJumpdest3.json", True), - ("jump0_outOfBoundary.json", True), - ("jump0_withoutJumpdest.json", True), - ("jump1.json", True), - ("jumpHigh.json", True), - ("jumpInsidePushWithJumpDest.json", True), - ("jumpInsidePushWithoutJumpDest.json", True), - ("jumpTo1InstructionafterJump_jumpdestFirstInstruction.json", True), - ("jumpTo1InstructionafterJump_noJumpDest.json", True), - ("jumpToUint64maxPlus1.json", True), - ("jumpToUintmaxPlus1.json", True), - ("JDfromStorageDynamicJump0_AfterJumpdest.json", True), - ("JDfromStorageDynamicJump0_AfterJumpdest3.json", True), - ("JDfromStorageDynamicJump0_withoutJumpdest.json", True), - ("JDfromStorageDynamicJump1.json", True), - ("JDfromStorageDynamicJumpInsidePushWithJumpDest.json", True), - ("JDfromStorageDynamicJumpInsidePushWithoutJumpDest.json", True), - ("DynamicJump0_outOfBoundary.json", True), - ("DynamicJump0_AfterJumpdest.json", True), - ("DynamicJump0_AfterJumpdest3.json", True), - ("DynamicJump0_withoutJumpdest.json", True), - ("DynamicJump1.json", True), - ("DynamicJumpInsidePushWithJumpDest.json", True), - ("DynamicJumpInsidePushWithoutJumpDest.json", True), - ("DynamicJumpJD_DependsOnJumps0.json", True), - ("DynamicJumpPathologicalTest1.json", True), - ("DynamicJumpPathologicalTest2.json", True), - ("DynamicJumpPathologicalTest3.json", True), - ("BlockNumberDynamicJump0_AfterJumpdest.json", True), - ("BlockNumberDynamicJump0_AfterJumpdest3.json", True), - ("BlockNumberDynamicJump0_withoutJumpdest.json", True), - ("BlockNumberDynamicJump1.json", True), - ("BlockNumberDynamicJumpInsidePushWithJumpDest.json", True), - ("BlockNumberDynamicJumpInsidePushWithoutJumpDest.json", True), - ("jump0_foreverOutOfGas.json", True), - ("JDfromStorageDynamicJump0_foreverOutOfGas.json", True), - ("DynamicJump0_foreverOutOfGas.json", True), - ("BlockNumberDynamicJump0_foreverOutOfGas.json", True), - ("jumpOntoJump.json", True), - ("DynamicJump_valueUnderflow.json", True), - ("stack_loop.json", True), - ], -) -def test_jump( - fork: Tuple[str, str], test_file: str, check_gas_left: bool -) -> None: - """Tests JUMP operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, test_file, check_gas_left=check_gas_left - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file, check_gas_left", - [ - ("jumpi1.json", True), - ("jumpiAfterStop.json", True), - ("jumpi_at_the_end.json", True), - ("JDfromStorageDynamicJumpi1.json", False), - ("JDfromStorageDynamicJumpiAfterStop.json", False), - ("DynamicJumpi1.json", True), - ("DynamicJumpiAfterStop.json", True), - ("BlockNumberDynamicJumpi1.json", True), - ("BlockNumberDynamicJumpiAfterStop.json", True), - ("jumpi0.json", True), - ("jumpi1_jumpdest.json", True), - ("jumpifInsidePushWithJumpDest.json", True), - ("jumpifInsidePushWithoutJumpDest.json", True), - ("jumpiOutsideBoundary.json", True), - ("jumpiToUint64maxPlus1.json", True), - ("jumpiToUintmaxPlus1.json", True), - ("JDfromStorageDynamicJumpi0.json", True), - ("JDfromStorageDynamicJumpi1_jumpdest.json", True), - ("JDfromStorageDynamicJumpifInsidePushWithJumpDest.json", True), - ("JDfromStorageDynamicJumpifInsidePushWithoutJumpDest.json", True), - ("JDfromStorageDynamicJumpiOutsideBoundary.json", True), - ("DynamicJumpi0.json", True), - ("DynamicJumpi1_jumpdest.json", True), - ("DynamicJumpifInsidePushWithJumpDest.json", True), - ("DynamicJumpifInsidePushWithoutJumpDest.json", True), - ("DynamicJumpiOutsideBoundary.json", True), - ("BlockNumberDynamicJumpi0.json", True), - ("BlockNumberDynamicJumpi1_jumpdest.json", True), - ("BlockNumberDynamicJumpifInsidePushWithJumpDest.json", True), - ("BlockNumberDynamicJumpifInsidePushWithoutJumpDest.json", True), - ("BlockNumberDynamicJumpiOutsideBoundary.json", True), - ], -) -def test_jumpi( - fork: Tuple[str, str], test_file: str, check_gas_left: bool -) -> None: - """Tests JUMPI operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, test_file, check_gas_left=check_gas_left - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "pc0.json", - "pc1.json", - ], -) -def test_pc(fork: Tuple[str, str], test_file: str) -> None: - """Tests PC operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - ["gas0.json", "gas1.json", "gasOverFlow.json"], -) -def test_gas(fork: Tuple[str, str], test_file: str) -> None: - """Tests GAS operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "for_loop1.json", - "for_loop2.json", - "loop_stacklimit_1020.json", - "loop_stacklimit_1021.json", - ], -) -def test_loop(fork: Tuple[str, str], test_file: str) -> None: - """Tests loop operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_when(fork: Tuple[str, str]) -> None: - """Tests conditional operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "when.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "byte1.json", - "calldatacopyMemExp.json", - "codecopyMemExp.json", - "deadCode_1.json", - "dupAt51becameMload.json", - "swapAt52becameMstore.json", - "log1MemExp.json", - ], -) -def test_miscellaneous(fork: Tuple[str, str], test_file: str) -> None: - """Tests miscellaneous control flow operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) diff --git a/tests/json_infra/vm/test_environmental_operations.py b/tests/json_infra/vm/test_environmental_operations.py deleted file mode 100644 index 66bd000652..0000000000 --- a/tests/json_infra/vm/test_environmental_operations.py +++ /dev/null @@ -1,138 +0,0 @@ -"""Tests for environmental opcodes.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmEnvironmentalInfo" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "address0.json", - "address1.json", - ], -) -def test_address(fork: Tuple[str, str], test_file: str) -> None: - """Tests ADDRESS opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_origin(fork: Tuple[str, str]) -> None: - """Tests ORIGIN opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "origin.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_caller(fork: Tuple[str, str]) -> None: - """Tests CALLER opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "caller.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_callvalue(fork: Tuple[str, str]) -> None: - """Tests CALLVALUE opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "callvalue.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "calldataload0.json", - "calldataload1.json", - "calldataload2.json", - "calldataload_BigOffset.json", - "calldataloadSizeTooHigh.json", - "calldataloadSizeTooHighPartial.json", - ], -) -def test_calldataload(fork: Tuple[str, str], test_file: str) -> None: - """Tests CALLDATALOAD opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "calldatasize0.json", - "calldatasize1.json", - "calldatasize2.json", - ], -) -def test_calldatasize(fork: Tuple[str, str], test_file: str) -> None: - """Tests CALLDATASIZE opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "calldatacopy0.json", - "calldatacopy1.json", - "calldatacopy2.json", - "calldatacopyZeroMemExpansion.json", - "calldatacopy_DataIndexTooHigh.json", - "calldatacopy_DataIndexTooHigh2.json", - "calldatacopy_sec.json", - "calldatacopyUnderFlow.json", - "calldatacopy0_return.json", - "calldatacopy1_return.json", - "calldatacopy2_return.json", - "calldatacopyZeroMemExpansion_return.json", - "calldatacopy_DataIndexTooHigh_return.json", - "calldatacopy_DataIndexTooHigh2_return.json", - ], -) -def test_calldatacopy(fork: Tuple[str, str], test_file: str) -> None: - """Tests CALLDATACOPY opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_codesize(fork: Tuple[str, str]) -> None: - """Tests CODESIZE opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "codesize.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "codecopy0.json", - "codecopyZeroMemExpansion.json", - "codecopy_DataIndexTooHigh.json", - ], -) -def test_codecopy(fork: Tuple[str, str], test_file: str) -> None: - """Tests CODECOPY opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_gasprice(fork: Tuple[str, str]) -> None: - """Tests GASPRICE opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, "gasprice.json") diff --git a/tests/json_infra/vm/test_keccak.py b/tests/json_infra/vm/test_keccak.py deleted file mode 100644 index a3d35c3b30..0000000000 --- a/tests/json_infra/vm/test_keccak.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Tests for the Keccak EVM opcode.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/vmSha3Test" -) -SPECIAL_TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmIOandFlowOperations" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "sha3_0.json", - "sha3_1.json", - "sha3_2.json", - "sha3_bigOffset2.json", - "sha3_memSizeNoQuadraticCost31.json", - "sha3_memSizeQuadraticCost32.json", - "sha3_memSizeQuadraticCost32_zeroSize.json", - "sha3_memSizeQuadraticCost33.json", - "sha3_memSizeQuadraticCost63.json", - "sha3_memSizeQuadraticCost64.json", - "sha3_memSizeQuadraticCost64_2.json", - "sha3_memSizeQuadraticCost65.json", - "sha3_3.json", - "sha3_4.json", - "sha3_5.json", - "sha3_6.json", - "sha3_bigOffset.json", - "sha3_bigSize.json", - ], -) -def test_sha3_succeeds(fork: Tuple[str, str], test_file: str) -> None: - """Tests successful SHA3 operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_sha3_fails_out_of_gas_memory_expansion(fork: Tuple[str, str]) -> None: - """ - Tests SHA3 operations that fail due to out of gas on - memory expansion. - """ - VmTestLoader(*fork).run_test(SPECIAL_TEST_DIR, "sha3MemExp.json") diff --git a/tests/json_infra/vm/test_logging_operations.py b/tests/json_infra/vm/test_logging_operations.py deleted file mode 100644 index 22dd1df273..0000000000 --- a/tests/json_infra/vm/test_logging_operations.py +++ /dev/null @@ -1,119 +0,0 @@ -"""Tests for the LOG* series of operations.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/vmLogTest" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "log0_emptyMem.json", - "log0_logMemsizeZero.json", - "log0_nonEmptyMem.json", - "log0_nonEmptyMem_logMemSize1.json", - "log0_nonEmptyMem_logMemSize1_logMemStart31.json", - "log0_logMemsizeTooHigh.json", - "log0_logMemStartTooHigh.json", - ], -) -def test_log0(fork: Tuple[str, str], test_file: str) -> None: - """Tests LOG0 operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "log1_Caller.json", - "log1_emptyMem.json", - "log1_logMemsizeZero.json", - "log1_MaxTopic.json", - "log1_nonEmptyMem.json", - "log1_nonEmptyMem_logMemSize1.json", - "log1_nonEmptyMem_logMemSize1_logMemStart31.json", - "log1_logMemsizeTooHigh.json", - "log1_logMemStartTooHigh.json", - ], -) -def test_log1(fork: Tuple[str, str], test_file: str) -> None: - """Tests LOG1 operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "log2_Caller.json", - "log2_emptyMem.json", - "log2_logMemsizeZero.json", - "log2_MaxTopic.json", - "log2_nonEmptyMem.json", - "log2_nonEmptyMem_logMemSize1.json", - "log2_nonEmptyMem_logMemSize1_logMemStart31.json", - "log2_logMemsizeTooHigh.json", - "log2_logMemStartTooHigh.json", - ], -) -def test_log2(fork: Tuple[str, str], test_file: str) -> None: - """Tests LOG2 operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "log3_Caller.json", - "log3_emptyMem.json", - "log3_logMemsizeZero.json", - "log3_MaxTopic.json", - "log3_nonEmptyMem.json", - "log3_nonEmptyMem_logMemSize1.json", - "log3_nonEmptyMem_logMemSize1_logMemStart31.json", - "log3_PC.json", - "log3_logMemsizeTooHigh.json", - "log3_logMemStartTooHigh.json", - ], -) -def test_log3(fork: Tuple[str, str], test_file: str) -> None: - """Tests LOG3 operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "log4_Caller.json", - "log4_emptyMem.json", - "log4_logMemsizeZero.json", - "log4_MaxTopic.json", - "log4_nonEmptyMem.json", - "log4_nonEmptyMem_logMemSize1.json", - "log4_nonEmptyMem_logMemSize1_logMemStart31.json", - "log4_PC.json", - "log4_logMemsizeTooHigh.json", - "log4_logMemStartTooHigh.json", - ], -) -def test_log4(fork: Tuple[str, str], test_file: str) -> None: - """Tests LOG4 operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) diff --git a/tests/json_infra/vm/test_memory_operations.py b/tests/json_infra/vm/test_memory_operations.py deleted file mode 100644 index 7bea861870..0000000000 --- a/tests/json_infra/vm/test_memory_operations.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Tests for memory operations in the EVM.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmIOandFlowOperations" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "mstore0.json", - "mstore1.json", - "mstoreMemExp.json", - ], -) -def test_mstore(fork: Tuple[str, str], test_file: str) -> None: - """Tests MSTORE operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "mstore8_0.json", - "mstore8_1.json", - "mstore8WordToBigError.json", - "mstore8MemExp.json", - ], -) -def test_mstore8(fork: Tuple[str, str], test_file: str) -> None: - """Tests MSTORE8 operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "mloadError0.json", - "mloadError1.json", - "mstore_mload0.json", - "mloadOutOfGasError2.json", - ], -) -def test_mload(fork: Tuple[str, str], test_file: str) -> None: - """Tests MLOAD operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "mstore_mload0.json", - ], -) -def test_mstore_mload(fork: Tuple[str, str], test_file: str) -> None: - """Tests combined MSTORE and MLOAD operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "msize0.json", - "msize1.json", - "msize2.json", - "msize3.json", - ], -) -def test_msize(fork: Tuple[str, str], test_file: str) -> None: - """Tests MSIZE operations using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) diff --git a/tests/json_infra/vm/test_stack_operations.py b/tests/json_infra/vm/test_stack_operations.py deleted file mode 100644 index 6e15793c34..0000000000 --- a/tests/json_infra/vm/test_stack_operations.py +++ /dev/null @@ -1,131 +0,0 @@ -"""Tests for the stack related opcodes.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -PUSH_TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmPushDupSwapTest" -) -POP_TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmIOandFlowOperations" -) - -DUP_TEST_DIR = SWAP_TEST_DIR = PUSH_TEST_DIR - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file, check_gas_left", - [(f"push{i}.json", True) for i in range(1, 34)] - + [ - ("push32Undefined2.json", True), - ("push32AndSuicide.json", False), - ], -) -def test_push_successfully( - fork: Tuple[str, str], test_file: str, check_gas_left: bool -) -> None: - """ - Tests successful PUSH operations using VM test - fixtures. - """ - VmTestLoader(*fork).run_test( - PUSH_TEST_DIR, test_file, check_gas_left=check_gas_left - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "push1_missingStack.json", - "push32Undefined.json", - "push32Undefined3.json", - "push32FillUpInputWithZerosAtTheEnd.json", - ], -) -def test_push_failed(fork: Tuple[str, str], test_file: str) -> None: - """ - Tests PUSH operations that should fail using - VM test fixtures. - """ - VmTestLoader(*fork).run_test(PUSH_TEST_DIR, test_file) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_dup(fork: Tuple[str, str]) -> None: - """ - Tests DUP operations for all variants (DUP1-DUP16) using - VM test fixtures. - """ - for i in range(1, 17): - VmTestLoader(*fork).run_test(DUP_TEST_DIR, f"dup{i}.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_dup_error(fork: Tuple[str, str]) -> None: - """ - Tests DUP operations that should produce errors using - VM test fixtures. - """ - VmTestLoader(*fork).run_test(DUP_TEST_DIR, "dup2error.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_swap(fork: Tuple[str, str]) -> None: - """ - Tests SWAP operations for all variants (SWAP1-SWAP16) - using VM test fixtures. - """ - for i in range(1, 17): - VmTestLoader(*fork).run_test(SWAP_TEST_DIR, f"swap{i}.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_swap_jump(fork: Tuple[str, str]) -> None: - """ - Tests SWAP operations combined with jump instructions - using VM test fixtures. - """ - VmTestLoader(*fork).run_test(SWAP_TEST_DIR, "swapjump1.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_swap_error(fork: Tuple[str, str]) -> None: - """ - Tests SWAP operations that should produce errors using - VM test fixtures. - """ - VmTestLoader(*fork).run_test(SWAP_TEST_DIR, "swap2error.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_pop(fork: Tuple[str, str]) -> None: - """Tests POP operation using VM test fixtures.""" - VmTestLoader(*fork).run_test(POP_TEST_DIR, "pop0.json") - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_pop_fails_when_stack_underflowed(fork: Tuple[str, str]) -> None: - """ - Tests that POP fails when the stack underflows using - VM test fixtures. - """ - VmTestLoader(*fork).run_test(POP_TEST_DIR, "pop1.json") diff --git a/tests/json_infra/vm/test_storage_operations.py b/tests/json_infra/vm/test_storage_operations.py deleted file mode 100644 index 051087c61e..0000000000 --- a/tests/json_infra/vm/test_storage_operations.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Tests for EVM storage operations.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmIOandFlowOperations" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file, check_gas_left", - [ - ("sstore_load_0.json", False), - ("sstore_load_1.json", False), - ("sstore_load_2.json", False), - ("sstore_underflow.json", True), - ("kv1.json", True), - ], -) -def test_sstore_and_sload( - fork: Tuple[str, str], test_file: str, check_gas_left: bool -) -> None: - """Tests SSTORE and SLOAD operations using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, test_file, check_gas_left=check_gas_left - ) diff --git a/tests/json_infra/vm/test_system_operations.py b/tests/json_infra/vm/test_system_operations.py deleted file mode 100644 index d359d28ff9..0000000000 --- a/tests/json_infra/vm/test_system_operations.py +++ /dev/null @@ -1,61 +0,0 @@ -"""Tests for EVM system operations.""" - -from typing import Tuple - -import pytest - -from .. import TEST_FIXTURES -from ..helpers.load_vm_tests import VmTestLoader -from . import FORKS - -ETHEREUM_TESTS_PATH = TEST_FIXTURES["ethereum_tests"]["fixture_path"] -TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/" - "vmSystemOperations" -) -VM_TEST_DIR = ( - f"{ETHEREUM_TESTS_PATH}/LegacyTests/Constantinople/VMTests/vmTests" -) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file, check_gas_left", - [ - ("suicide0.json", False), - ("suicideNotExistingAccount.json", False), - ("suicideSendEtherToMe.json", False), - ], -) -def test_seldestruct( - fork: Tuple[str, str], test_file: str, check_gas_left: bool -) -> None: - """Tests selfdestruct opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test( - TEST_DIR, test_file, check_gas_left=check_gas_left - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -def test_seldestruct_vm_test(fork: Tuple[str, str]) -> None: - """Tests selfdestruct opcode using legacy VM test suicide fixture.""" - VmTestLoader(*fork).run_test( - VM_TEST_DIR, "suicide.json", check_gas_left=False - ) - - -@pytest.mark.vm_test -@pytest.mark.parametrize("fork", FORKS) -@pytest.mark.parametrize( - "test_file", - [ - "return0.json", - "return1.json", - "return2.json", - ], -) -def test_return(fork: Tuple[str, str], test_file: str) -> None: - """Tests return opcode using VM test fixtures.""" - VmTestLoader(*fork).run_test(TEST_DIR, test_file) From 5404596c2ace979a2c479577a8ce9a7d98db86de Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath Date: Fri, 28 Nov 2025 20:03:35 +0100 Subject: [PATCH 4/4] enhance(ci): run optimized tests selectively --- .github/actions/get-changed-files/action.yaml | 33 +++++++++++++++++++ .github/workflows/test.yaml | 26 +++------------ tests/json_infra/conftest.py | 5 ++- tests/json_infra/helpers/select_tests.py | 10 ++++-- tox.ini | 1 + 5 files changed, 51 insertions(+), 24 deletions(-) create mode 100644 .github/actions/get-changed-files/action.yaml diff --git a/.github/actions/get-changed-files/action.yaml b/.github/actions/get-changed-files/action.yaml new file mode 100644 index 0000000000..85d977c929 --- /dev/null +++ b/.github/actions/get-changed-files/action.yaml @@ -0,0 +1,33 @@ +name: Get Changed Files +description: Get list of changed files between base and head commits + +outputs: + file_list: + description: Path to the file containing the list of changed files + value: ${{ steps.get-changed-files.outputs.file_list }} + +runs: + using: composite + steps: + - name: Get changed files and save to disk + id: get-changed-files + shell: bash + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + BASE_SHA=$(git merge-base "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}") + HEAD_SHA="${{ github.event.pull_request.head.sha }}" + else + # On push or force push to the feature branch + BASE_SHA=$(git merge-base "${{ github.event.before }}" "${{ github.sha }}") + HEAD_SHA="${{ github.sha }}" + fi + + echo "Diffing commits: $BASE_SHA..$HEAD_SHA" + + # Get changed files and save to disk (use absolute path for reliability) + FILE_LIST="${GITHUB_WORKSPACE}/changed_files.txt" + git diff --name-only "$BASE_SHA" "$HEAD_SHA" > "$FILE_LIST" + echo "Changed files saved to $FILE_LIST" + echo "file_list=$FILE_LIST" >> $GITHUB_OUTPUT + echo "List of files changed in the PR" + cat $FILE_LIST diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 472c6e6eec..0117b8de27 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -94,27 +94,8 @@ jobs: with: python-version: "3.11" - uses: ./.github/actions/setup-env - - name: Get changed files and save to disk + - uses: ./.github/actions/get-changed-files id: get-changed-files - run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - BASE_SHA=$(git merge-base "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}") - HEAD_SHA="${{ github.event.pull_request.head.sha }}" - else - # On push or force push to the feature branch - BASE_SHA=$(git merge-base "${{ github.event.before }}" "${{ github.sha }}") - HEAD_SHA="${{ github.sha }}" - fi - - echo "Diffing commits: $BASE_SHA..$HEAD_SHA" - - # Get changed files and save to disk - FILE_LIST="changed_files.txt" - git diff --name-only "$BASE_SHA" "$HEAD_SHA" > "$FILE_LIST" - echo "Changed files saved to $FILE_LIST" - echo "file_list=$FILE_LIST" >> $GITHUB_OUTPUT - echo "List of files changed in the PR" - cat $FILE_LIST - name: Run json infra tests run: tox -e json_infra -- --file-list="${{ steps.get-changed-files.outputs.file_list }}" - name: Upload coverage reports to Codecov @@ -131,13 +112,16 @@ jobs: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 with: submodules: recursive + fetch-depth: 0 # Fetch full history for commit comparison - name: Setup Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 with: python-version: "3.11" - uses: ./.github/actions/setup-env + - uses: ./.github/actions/get-changed-files + id: get-changed-files - name: Run optimized tests - run: tox -e optimized + run: tox -e optimized -- --file-list="${{ steps.get-changed-files.outputs.file_list }}" tests_pytest_py3: runs-on: [self-hosted-ghr, size-xl-x64] diff --git a/tests/json_infra/conftest.py b/tests/json_infra/conftest.py index 7c3bae1171..d01dc45922 100644 --- a/tests/json_infra/conftest.py +++ b/tests/json_infra/conftest.py @@ -126,6 +126,7 @@ def pytest_configure(config: Config) -> None: ethereum.trace.set_evm_trace(Eip3155Tracer()) # Process fork range options + optimized = config.getoption("optimized") desired_fork = config.getoption("single_fork", "") forks_from = config.getoption("forks_from", "") forks_until = config.getoption("forks_until", "") @@ -162,7 +163,9 @@ def pytest_configure(config: Config) -> None: # Extract the fork range desired_forks = all_forks[start_idx:end_idx] elif file_list: - desired_forks = extract_affected_forks(config.rootpath, file_list) + desired_forks = extract_affected_forks( + config.rootpath, file_list, optimized + ) else: desired_forks = all_forks diff --git a/tests/json_infra/helpers/select_tests.py b/tests/json_infra/helpers/select_tests.py index 5ff1c25c25..602c5323a2 100644 --- a/tests/json_infra/helpers/select_tests.py +++ b/tests/json_infra/helpers/select_tests.py @@ -16,7 +16,9 @@ } -def extract_affected_forks(repo_root: Path, files_path: str) -> List[str]: +def extract_affected_forks( + repo_root: Path, files_path: str, optimized: bool +) -> List[str]: """ Extract fork names from changed file paths read from disk. @@ -24,6 +26,7 @@ def extract_affected_forks(repo_root: Path, files_path: str) -> List[str]: repo_root: Root directory of the repository config. files_path: Path to file containing changed file paths (one per line) + optimized: If optimized tests are being run. Returns: List of fork json_test_names that have been affected @@ -71,7 +74,10 @@ def extract_affected_forks(repo_root: Path, files_path: str) -> List[str]: # Run all forks if something changes in the evm # tools return all_forks - + if optimized and file_path.is_relative_to("src/ethereum_optimized"): + # Run all forks if something changes in the optimized tools and + # while running optimized environment. + return all_forks if file_path.is_relative_to("src/ethereum/"): parts = Path(file_path).parts if len(parts) < 4 or parts[2] != "forks": diff --git a/tox.ini b/tox.ini index e3698c9442..432c6ce2db 100644 --- a/tox.ini +++ b/tox.ini @@ -137,6 +137,7 @@ commands = --ignore-glob='tests/test_t8n.py' \ --basetemp="{temp_dir}/pytest" \ --optimized \ + {posargs} \ tests/json_infra [testenv:spec-docs]