-
Notifications
You must be signed in to change notification settings - Fork 70
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(fw): Gas test generator #719
base: main
Are you sure you want to change the base?
Conversation
Why? I tried and just wrapped |
No other issues, I meant working automatically, and yes I agree #610 should solve this. |
a19f3e2
to
5f35889
Compare
@pdobacz @shemnon I rebased to main and renamed this generator to I also added the EOF marker |
@shemnon @marioevz I'm totally on the fence with the #713 vs #719, ever so slightly in favor of this #719, just because it already has OOG testing and easier integration with the EOF marker and no GAS opcode dependency. Or is the plan to have both? Maybe this is the way, and we just write both kinds for each case to test, serving two slightly different purposes. Would other people on the testing team have a preference here? |
I think #713 is not generalized at the moment, and we could generalize it eventually, but it has been merged as a one-off function for the time being. I tagged other members of the testing team for them to have a look at the implementation but in my opinion having many generators for different purposes should be ok. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really like this idea!! There are so many ways we can extend this for other types of state test generators.
The refactor in the test is very clean! My only concern is that we are not being verbose enough with respect how we define the test, as we don't know where the required fixtures are going. Maybe decorating the test function like so:
@exact_gas_test(
state_test: StateTestFiller,
...
tx: Transaction,
gas_test_types=GasTestType.OOG,
with_data=True,
)
def test_mcopy_huge_memory_expansion():
pass
This could be a me problem though, and maybe its more obvious when writing the test.
tx=tx, | ||
) | ||
|
||
if with_data: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this still works if we move the with_data
logic witih the decorator:
def decorator(func: Callable[..., Any], with_data: bool) -> Callable[..., Any]:
@pytest.mark.parametrize(
"gas_test_type",
gas_test_types,
ids=lambda x: x.value,
)
def generated_gas_test(
pre: Alloc,
state_test: StateTestFiller,
exact_gas_cost: int,
gas_test_type: GasTestType,
bytecode: Bytecode,
data: bytes = None,
):
if with_data:
generator(
pre=pre,
state_test=state_test,
exact_gas_cost=exact_gas_cost,
gas_test_type=gas_test_type,
bytecode=bytecode,
data=data,
)
else:
generator(
pre=pre,
state_test=state_test,
exact_gas_cost=exact_gas_cost,
gas_test_type=gas_test_type,
bytecode=bytecode,
)
generated_gas_test.__name__ = func.__name__
generated_gas_test.__doc__ = func.__doc__
return generated_gas_test
if type(gas_test_types) is GasTestType: | ||
gas_test_types = [gas_test_types] | ||
|
||
assert type(gas_test_types) is list |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we assert all the required fixtures?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so nice! This automatic test generation is going to be so valuable.
However, I tend to prefer a pytest plugin approach instead of a library decorator that returns @pytest.mark.parametrize
:
- I'm not fond of moving the
state_test
call out of the test function (it's now directly called in the library helper). Apart from being unexpected, it means that the implementer can't modify any of the objects going to the state test,post
, for example (as it's set in the library function, it can't be extended by the implementer). - I'm also not keen on moving test parametrization to custom decorators that aren't exposed to pytest as we don't get a mark for these custom decorators (this means we can't filter by this type of test, for example). I.e., I'd prefer something like
@pytest.mark.generate_gas_test()
. I suspect we'll also run into problems applying xfail to subsets of these parametrized tests (but we could add a custom marks keyword as suggested for thewith_all_...
markers).
I created a rough POC for a pytest plugin, it doesn't modify post
yet, but I think it's possible: #760
🗒️ Description
Creates a gas test generator based off the
MCOPY
memory copy tests.It can be applied to *any test and the test writer only needs to provide a couple of fixtures for it to work.
*It only works on legacy EVM code at the moment and not EOF, but I have a couple of ideas of how to make it work.
🔗 Related Issues
None
✅ Checklist
mkdocs serve
locally and verified the auto-generated docs for new tests in the Test Case Reference are correctly formatted.