-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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: add timeouts to fuzz testing #9394
feat: add timeouts to fuzz testing #9394
Conversation
Adds --fuzz-timeout-secs to fuzz tests which will cause a property test to timeout after a certain number of seconds. Also adds --fuzz-allow-timeouts so that timeouts are optionally not considered to be failures.
Thank you! Supportive for such, let's have this
[fuzz]
timeout=60 which would be applied to all fuzz tests (I don't think the allow time is needed, just consider that if
/// forge-config: default.fuzz.timeout=60
function test_function_with_timeout(uint256 x) public {...}
Same configs could be applied for invariants too, e.g. [invariant]
timeout=60 and /// forge-config: default.invariant.timeout=60 Lmk if you have issues implementing these, can provide more details / help with |
@grandizzy cool, will start making these changes! Regarding allowing timeouts, it might be worth considering that some people may want some way to detect that a fuzz run took too long and timed out. For now I would just allow timeouts by default and if someone asks for the feature we can add |
23c9395
to
b2a5f8d
Compare
Ok @grandizzy went ahead and made various changes. Please note the change to use |
the problem with /// forge-config: default.fuzz.runs = 4294967295
/// forge-config: default.fuzz.timeout = 60
function testFuzz_SetNumber(uint256 x) public { the test still loops / consume cpu cycles for way more than 1 minute and don't think that's desired |
Ah yeah you're right, ok, will fix! |
75b81e0
to
b704851
Compare
@grandizzy I'm back to failing for timeouts, thanks for the tip there. I believe the PR works as-is, not exactly sure where I should be adding tests but happy to do so if you could point me to the test file I should modify! |
Awesome, could you please make sure
are passing, CI is failing now. Re tests, let's add one similar with foundry/crates/forge/tests/it/fuzz.rs Lines 213 to 215 in 31dd1f7
that set inline config for a big number of runs and a timeout of 5 seconds and we assert test is passing. you can test it as
|
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.
Last nit re invariant impl, let's fix clippy and format too
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.
lgtm, thank you! I made couple of changes as
- move logic to interrupt invariant test in depth loop
- add and reuse start_timer fn and TEST_TIMEOUT constant
- add fuzz and invariant tests
- fix failing test
Pending other reviews before merging
@grandizzy sweet! Let me know if I can help in any way. Thanks for all your review here, very much appreciated 🙏 |
if let Some((start_time, timeout)) = start_time { | ||
if start_time.elapsed() > timeout { |
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 guess since this is opt-in, checking via elapsed for now is fine, and we can track improvements separately, but I'd suggest to wrap this if let Some into a helper type like Timeout(Option<Instant>)
and an is_timed_out
then this becomes easier to change
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.
ac33250
to
da87095
Compare
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.
lgtm
* feat: add timeouts to fuzz testing Adds --fuzz-timeout-secs to fuzz tests which will cause a property test to timeout after a certain number of seconds. Also adds --fuzz-allow-timeouts so that timeouts are optionally not considered to be failures. * simplify timeout implementation * use u32 for timeout * switch back to failing for timeouts * clippy * Nits: - move logic to interrupt invariant test in depth loop - add and reuse start_timer fn and TEST_TIMEOUT constant - add fuzz and invariant tests - fix failing test * Fix fmt * Changes after review: introduce FuzzTestTimer --------- Co-authored-by: grandizzy <[email protected]>
Adds
--fuzz-timeout-secs
to fuzz tests which will cause a property test to timeout after a certain number of seconds. Also adds--fuzz-allow-timeouts
so that timeouts are optionally not considered to be failures.First time writing Rust so I have no idea if this is the idiomatic way of doing things, happy to change anything based on suggestions! Would also be great to understand where the best place is to add tests for this sort of PR.
Keeping this as a draft for now. I want to add support for the same feature within invariant tests but I couldn't easily understand how
FOUNDRY_INVARIANT_RUNS
actually gets parsed from the environment. ApparentlyFOUNDRY_INVARIANT_RUNS
can't be set in the CLI (there's no--invariant-runs
flag). Any pointers here would be much appreciated.This is sketch for #9393