Skip to content
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

feat(tests): Add multiple exception support to EOF tests #759

Merged
merged 4 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Test fixtures for use by clients are available for each release on the [Github r
- 🐞 Fixed fixture index generation on EOF tests ([#728](https://github.com/ethereum/execution-spec-tests/pull/728)).
- 🐞 Fixes consume genesis mismatch exception for hive based simulators ([#734](https://github.com/ethereum/execution-spec-tests/pull/734)).
- ✨ Adds reproducible consume commands to hiveview ([#717](https://github.com/ethereum/execution-spec-tests/pull/717)).
- 💥 Added multiple exceptions to the EOF fixture format ([#759](https://github.com/ethereum/execution-spec-tests/pull/759)).
- ✨ Added optional parameter to all `with_all_*` markers to specify a lambda function that filters the parametrized values ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)).
- ✨ Added [`extend_with_defaults` utility function](https://ethereum.github.io/execution-spec-tests/main/writing_tests/writing_a_new_test/#ethereum_test_tools.utility.pytest.extend_with_defaults), which helps extend test case parameter sets with default values. `@pytest.mark.parametrize` ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)).
- ✨ Added `Container.Init` to `ethereum_test_types.EOF.V1` package, which allows generation of an EOF init container more easily ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)).
Expand All @@ -37,6 +38,10 @@ Test fixtures for use by clients are available for each release on the [Github r
- ✨ Releases for feature eip7692 now include both Cancun and Prague based tests in the same release, in files `fixtures_eip7692.tar.gz` and `fixtures_eip7692-prague.tar.gz` respectively ([#743](https://github.com/ethereum/execution-spec-tests/pull/743)).
- 🔀 Simplify Python project configuration and consolidate it into `pyproject.toml` ([#764](https://github.com/ethereum/execution-spec-tests/pull/764)).

### 💥 Breaking Change

- The EOF fixture format contained in `eof_tests` may now contain multiple exceptions in the `"exception"` field in the form of a pipe (`|`) separated string ([#759](https://github.com/ethereum/execution-spec-tests/pull/759)).

## [v3.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v3.0.0) - 2024-07-22

### 🧪 Test Cases
Expand Down
6 changes: 4 additions & 2 deletions src/ethereum_test_exceptions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
BlockException,
BlockExceptionInstanceOrList,
EOFException,
EOFExceptionInstanceOrList,
ExceptionInstanceOrList,
TransactionException,
TransactionExceptionInstanceOrList,
Expand All @@ -16,10 +17,11 @@
__all__ = [
"BlockException",
"BlockExceptionInstanceOrList",
"EngineAPIError",
"EOFException",
"EOFExceptionInstanceOrList",
"EngineAPIError",
"EvmoneExceptionMapper",
"ExceptionInstanceOrList",
"TransactionException",
"TransactionExceptionInstanceOrList",
"EvmoneExceptionMapper",
]
3 changes: 3 additions & 0 deletions src/ethereum_test_exceptions/evmone_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ class EvmoneExceptionMapper:
),
ExceptionMessage(EOFException.STACK_HEIGHT_MISMATCH, "err: stack_height_mismatch"),
ExceptionMessage(EOFException.TOO_MANY_CONTAINERS, "err: too_many_container_sections"),
ExceptionMessage(
EOFException.INVALID_CODE_SECTION_INDEX, "err: invalid_code_section_index"
),
)

def __init__(self) -> None:
Expand Down
14 changes: 14 additions & 0 deletions src/ethereum_test_exceptions/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,14 @@ class EOFException(ExceptionBase):
"""
EOF container header has too many sub-containers.
"""
INVALID_CODE_SECTION_INDEX = auto()
"""
CALLF Operation referes to a non-existent code section
"""
UNEXPECTED_HEADER_KIND = auto()
"""
Header parsing encounterd a section kind it wasn't expecting
"""


"""
Expand All @@ -753,3 +761,9 @@ class EOFException(ExceptionBase):
BeforeValidator(from_pipe_str),
PlainSerializer(to_pipe_str),
]

EOFExceptionInstanceOrList = Annotated[
List[EOFException] | EOFException,
BeforeValidator(from_pipe_str),
PlainSerializer(to_pipe_str),
]
4 changes: 2 additions & 2 deletions src/ethereum_test_fixtures/eof.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pydantic import Field

from ethereum_test_base_types import Bytes, CamelModel, Number
from ethereum_test_exceptions import EOFException
from ethereum_test_exceptions.exceptions import EOFExceptionInstanceOrList
from ethereum_test_types.eof.v1 import ContainerKind

from .base import BaseFixture
Expand All @@ -20,7 +20,7 @@ class Result(CamelModel):
Result for a single fork in a fixture.
"""

exception: EOFException | None = None
exception: EOFExceptionInstanceOrList | None = None
valid: bool = Field(..., alias="result")

def model_post_init(self, __context: Any) -> None:
Expand Down
37 changes: 20 additions & 17 deletions src/ethereum_test_specs/eof.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from pydantic import Field, model_validator

from ethereum_test_base_types import Account, Bytes
from ethereum_test_exceptions import EOFException, EvmoneExceptionMapper
from ethereum_test_exceptions import EvmoneExceptionMapper
from ethereum_test_exceptions.exceptions import EOFExceptionInstanceOrList, to_pipe_str
from ethereum_test_fixtures import BaseFixture, FixtureFormats
from ethereum_test_fixtures.eof import Fixture, Result, Vector
from ethereum_test_forks import Fork
Expand Down Expand Up @@ -136,7 +137,7 @@ class EOFTest(BaseTest):
"""

data: Bytes
expect_exception: EOFException | None = None
expect_exception: EOFExceptionInstanceOrList | None = None
container_kind: ContainerKind | None = None

supported_fixture_formats: ClassVar[List[FixtureFormats]] = [
Expand Down Expand Up @@ -237,21 +238,23 @@ def verify_result(self, result: CompletedProcess, expected_result: Result, code:
raise UnexpectedEOFException(
code=code, got=f"{actual_exception} ({actual_message})"
)

expected_exception = expected_result.exception
expected_message = parser.exception_to_message(expected_exception)

if "OK" in actual_message:
raise ExpectedEOFException(
code=code, expected=f"{expected_exception} ({expected_message})"
)

if expected_exception != actual_exception:
raise EOFExceptionMismatch(
code=code,
expected=f"{expected_exception} ({expected_message})",
got=f"{actual_exception} ({actual_message})",
)
else:
expected_string = to_pipe_str(expected_result.exception)
print(expected_string)
print(actual_exception)
if "OK" in actual_message:
raise ExpectedEOFException(
code=code,
expected=f"{expected_string}",
)
elif actual_exception in expected_result.exception:
return
else:
raise EOFExceptionMismatch(
code=code,
expected=f"{expected_string}",
got=f"{actual_exception} ({actual_message})",
)

def generate(
self,
Expand Down
4 changes: 2 additions & 2 deletions src/ethereum_test_types/eof/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from ethereum_test_base_types import Bytes
from ethereum_test_base_types.conversions import BytesConvertible
from ethereum_test_base_types.pydantic import CopyValidateModel
from ethereum_test_exceptions import EOFException
from ethereum_test_exceptions.exceptions import EOFExceptionInstanceOrList
from ethereum_test_vm import Bytecode
from ethereum_test_vm import Opcodes as Op

Expand Down Expand Up @@ -365,7 +365,7 @@ class Container(CopyValidateModel):
Body: type section first, all code sections, data section(s), last
container sections
"""
validity_error: EOFException | str | None = None
validity_error: EOFExceptionInstanceOrList | str | None = None
"""
Optional error expected for the container.

Expand Down
Loading