-
Notifications
You must be signed in to change notification settings - Fork 17.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
proposal: testing: support naming seed corpus values provided with (*testing.F).Add #50456
Comments
CC @dnwe |
While this will work just fine for the call sites, it would make for a pretty tricky signature: It would be a lot saner if we did |
For completeness: I realise this is also an option, but leaving |
This proposal has been added to the active column of the proposals project |
It's getting very late to change the API, so it's looking like AddNamed is the right approach? Another possibility is to define a new string type like testing.FuzzName and then you could
but that's a bit verbose. |
I reckon we're not late to change the API; this user report was given three weeks ago, a couple of weeks after the beta came out. That's very much within the timeframe that you would expect users to give the beta an honest try and report issues. At the time of writing there are 38 open issues with the I do think we need this feature; if we say "one shouldn't need to name seed corpus entries", presumably the same could have applied to sub-test and sub-benchmark names :) And I still believe that altering |
Also, if it comes between AddNamed and FuzzName, my vote would go for FuzzName; that way we avoid two "add" entrypoints, and it's clear which argument is the name versus the variable number of fuzz values. Finally, just a thought: I seem to recall that the proposal review committee only meets once a week, and the RC isn't very far, so we should probably expedite a resolution here before more weeks go by and we really are too late. |
It seems like we'll get beta2 next week, which seems to support my reasoning above - the RC is probably four weeks away or so. And, if we can manage to get this small change into master early next week, users can also test it as part of beta2 :) |
I am not sure about the need to name specific seed values. This reminds me of the pets vs cattle discussion for managing computers. Every test function we write is typically an important, unique, carefully tended thing (like a pet). We are talking about adding complexity, and I am not convinced we have established that the complexity is needed. |
Perhaps you're right that not every seed corpus entry will need a name, but I think that already applies to sub-tests and sub-benchmarks - one can leave the name empty and they get a number instead. That seems like the best of both worlds to me.
That assumption worries me a little; most of the fuzzers I've written take bytes or strings as input, and some of those inputs do get reasonably long fairly quickly when I want the seed corpus to also cover some particularly interesting and complex edge cases. That said, if we think that unnamed seed corpus entries will be more common, then perhaps the FuzzName solution is a good middle ground. I can't say I have enough data to point one way or another. I'm not sure if the comparison with package constraints applies; we can always add that package in 1.19, whereas we can't change the signature of |
I don't think that adding the
|
I originally raised this merely as an API discrepancy rather than necessarily a strong desire for the capability. My 2p would be that I similarly think that the functionality we gain isn't worth the overhead and unintuitiveness of a special If it's too late to make |
(I actually prefer storing my seed values under the testdata hierarchy anyway) |
One option could be to combine ideas from #46780 and #47413 and add support for func FuzzFoo(f *testing.F) {
for _, tc := range []struct {
name string
s string
expected int
}{
{name: "random", s: "a3g1f3", expected: 10},
{name: "dashes", s: "----", expected: 100},
{name: "empty", s: "", expected: 0},
} {
tc := tc
f.Run(tc.name, func(f *testing.F) {
// test tc
if res := foo(tc.s); res != tc.expected {
f.Errorf("foo(%s) = %d, want %d", tc.s, res, tc.expected)
}
f.Add(tc.s) // named tc.name
})
}
f.Fuzz(...)
}
Interestingly, I prefer my seed values to be a part of the table-driver test. |
@mvdan I would have thought that large seed inputs would be better handled as files under testdata/fuzz than placed in programs? Or are these mechanically constructed seeds? |
what do you do after fuzzing found an interesting input and dumps it in testdata for you to re-run against? Do you manually move it to your seed table or do you just discard it after you’ve fixed the crasher? |
That, with an expected result or error. For example: https://github.com/FerretDB/FerretDB/blob/main/internal/bson/double_test.go (It would be nice to have some tooling for that or a function to read seed corpus files, but that's offtopic) |
It sounds like this is either a likely decline or a 'on hold'. Given that we are not making changes for Go 1.18, perhaps it should be declined for now, and then a new proposal with a different API can be proposed if we need it? |
I admit I hadn't realised it was supported to add seed corpus entries directly as files while using custom names. Taking another look at https://go.dev/doc/fuzz/, I do see it's mentioned. If one seed input is too large to be named after its own value, then I think it's a reasonable tradeoff to instead include it as a named file. I do have one case where I'm mechanically constructing reasonably sized seeds, but I'm not sure that it would be a huge problem either. I could always write a
I've grown less convinced that we need this feature right now as the conversation has progressed; declining for now seems reasonable. |
Based on the discussion above, this proposal seems like a likely decline. |
No change in consensus, so declined. |
Seed corpus entries can be added to a fuzz test by calling
(*testing.F).Add
. There is no way to name these seed corpus entries, so they default to "seed#{num}". When run withgo test -v
, it will look something like this:The proposal is to allow a way to name these entries, much like you would with an execution of
t.Run
. This would help with error messages and debugging. We could do this a few different ways:f.Add
to accept an optional first/last name string param. Sincef.Add
takes a[]interface{}
today, this is functionality that could be added later that wouldn't break backwards compatibility.e.g. existing fuzz tests that look like this:
would change to
*testing.F
. For example:(*testing.F).AddNamed(string, []interface{})
Originally proposed by @dnwe
/cc @golang/fuzzing
The text was updated successfully, but these errors were encountered: