-
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: ux fuzz invariant #4744
feat: ux fuzz invariant #4744
Conversation
Unit tests
…d text Unit tests
Unit tests
Meaningful e2e test
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 appreciate this.
before we proceed with this, we should discuss how exactly this would look like in the toml file.
could you please add same examples so we can discuss,
cc @mds1
Hi @mattsse, This works inlining config comments in solidity test functions, to override wider scoped E2E tests can help to understand:
Let's discuss this. |
@mattsse I don't think we should need any config file changes here. Like @0xMelkor said, the idea is that the toml file's profiles would give the default config, and you can override the config at the file, contract, or test level using comments like this Hey @0xMelkor, should this work yet? I setup a new project and modified the default tests to look like this: pragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "../src/Counter.sol";
contract CounterTest is Test {
Counter public counter;
function setUp() public {
counter = new Counter();
counter.setNumber(0);
}
function testSetNumberNoChange(uint256 x) public {
counter.setNumber(x);
assertEq(counter.number(), x);
}
// forge-config: default.fuzz.runs = 111
// forge-config: ci.fuzz.runs = 222
function testSetNumberCustom(uint256 x) public {
counter.setNumber(x);
assertEq(counter.number(), x);
}
} And the config file looks like this: [profile.ci]
fuzz = { runs = 1000 } But when I run this branch, |
Ah got it, sorry didn't realize! This design lgtm, cc @mattsse @PaulRBerg @PatrickAlphaC for any final thoughts on UX here. Per the discussion in #3062 I think one important part is throwing an error if we see a comment that starts with |
The proposed design looks great, thanks for picking up this task @0xMelkor! I agree with @mds1 that it would be helpful to throw an error when the comment contains an erroneous config. If we don't do this, there will be lots and lots of red herrings in Foundry code bases, i.e. comments that mislead readers by making them believe there is a bespoke fuzzing configuration when in fact there isn't any. Regarding execution - the comment config will be disregarded if it refers to a profile other than the one used by Forge during runtime, correct? |
- TestOptions struct extended to track test specific configs - Tests
Nice!! pragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "../src/Counter.sol";
contract CounterTest is Test {
Counter public counter;
function setUp() public {
counter = new Counter();
counter.setNumber(0);
}
// forge-config: default.invariant.fail_on_revert = false
function invariant_SetNumberCustom() public {
assert(counter.number() < 100);
}
} |
Yes this field is mapped foundry/config/src/invariant.rs Line 62 in 7d540c0
The difference is that it must be provided in kebab case: // forge-config: default.invariant.fail-on-revert = false
function invariant_SetNumberCustom() public {
assert(counter.number() < 100);
} This PR is still in draft. Very soon these configs will be applied at execution time. |
Hi guys, Fuzz inline configs are interpreted and applied at runtime. I added some tests that confirm my assertion. |
Suggestions applied @Evalir |
…the foundry.toml path cannot be resolved
Some tests were failing because the new logic cannot find a foundry/cli/src/cmd/forge/test/mod.rs Line 155 in fa97f9a
For such reason I added a fallback value in the case the file doesn't exist: Lines 182 to 187 in fa97f9a
Is this acceptable? Failing tests:
|
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.
Changes look good, but failed tests are ominous,
passing on master
some of them look config-related I think.
what's the reason they're failing?
No more problems with tests. |
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 lgtm—just the nit on the InlineConfigParser
impls
// self is Copy. We clone it with dereference. | ||
let mut conf_clone = *self; |
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.
ok so if i understand correctly this is a copy that we're later mutating and returning? can we do self.clone()
? This doesn't seem too idiomatic
/// The inner error | ||
pub source: InlineConfigParserError, |
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.
Right now the error looks like this:
Inline config Error detected at test/Counter.t.sol:CounterTest:testSetNumber1:"288:82:20"
Not sure if useful, but I think @mattsse added an offset_to_line
to the forge fmt error messages which may useful to get a line number here. Or if we can get rid of the quotes around the 288:82:20
that might look a bit nicer
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.
Two small comments otherwise this is awesome and looks great! |
Hi guys, |
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.
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.
Sick! Happy with the changes too—merging! Amazing work @0xMelkor ❤️ |
Awesome! |
Motivation
Provide a solution for #3062, #4085 and updates #3411.
As described in the issue we are going to support Solidity comments as a new configuration source.
Solution
Tasks
FuzzConfig
,InvariantConfig
)profile
(ci, default, ecc.)ProjectCompileOutput
to extract inline per-test configs.TestOptions
.NOTE:
For the sake of KISS I used a standalone parser (
ConfParser
) instead of afigment::Provider
. If you prefer the second approach just tell me.Cheers