Recently the Go team released a fuzzer https://blog.golang.org/fuzz-beta
Can you help to describe what I can expect from the fuzzer in terms of test goals?
How to apply the fuzzer?
Give some insight about how long we would run it before considering it good enough
How to correlate execution failure with the code (i expect having GB of results, I am wondering how overwhelming that could be and how to handle that)
See this intentionally terrific piece of code which would definitely need to be fuzzed
package main
import (
"fmt"
"log"
)
func main() {
type expectation struct {
input string
output []string
}
expectations := []expectation{
expectation{
input: "foo=bar baz baz foo:1 baz ",
output: []string{
"foo=bar baz baz",
"foo:1 baz",
},
},
expectation{
input: "foo=bar baz baz foo:1 baz foo:234.mds32",
output: []string{
"foo=bar baz baz",
"foo:1 baz",
"foo:234.mds32",
},
},
expectation{
input: "foo=bar baz baz foo:1 baz foo:234.mds32 notfoo:baz foo:bak foo=bar baz foo:nospace foo:bar",
output: []string{
"foo=bar baz baz",
"foo:1 baz",
"foo:234.mds32",
"notfoo:baz",
"foo:bak",
"foo=bar baz",
"foo:nospace",
"foo:bar",
},
},
expectation{
input: "foo=bar",
output: []string{
"foo=bar",
},
},
expectation{
input: "foo",
output: []string{
"foo",
},
},
expectation{
input: "=bar",
output: []string{
"=bar",
},
},
expectation{
input: "foo=bar baz baz foo:::1 baz ",
output: []string{
"foo=bar baz baz",
"foo:::1 baz",
},
},
expectation{
input: "foo=bar baz baz foo:::1 baz ",
output: []string{
"foo=bar baz baz",
"foo:::1 baz",
},
},
}
for i, expectation := range expectations {
fmt.Println(" ==== TEST ", i)
success := true
res := parse(expectation.input)
if len(res) != len(expectation.output) {
log.Printf("invalid length of results for test %v\nwanted %#v\ngot %#v", i, expectation.output, res)
success = false
}
for e, r := range res {
if expectation.output[e] != r {
log.Printf("invalid result for test %v at index %v\nwanted %#v\ngot %#v", i, e, expectation.output, res)
success = false
}
}
if success {
fmt.Println(" ==== SUCCESS")
} else {
fmt.Println(" ==== FAILURE")
break
}
fmt.Println()
}
}
func parse(input string) (kvs []string) {
var lastSpace int
var nextLastSpace int
var n int
var since int
for i, r := range input {
if r == ' ' {
nextLastSpace = i + 1
if i > 0 && input[i-1] == ' ' {
continue
}
lastSpace = i
} else if r == '=' || r == ':' {
if n == 0 {
n++
continue
}
n++
if since < lastSpace {
kvs = append(kvs, string(input[since:lastSpace]))
}
if lastSpace < nextLastSpace { // there was multiple in between spaces.
since = nextLastSpace
} else {
since = lastSpace + 1
}
}
}
if since < len(input) { // still one entry
var begin int
var end int
begin = since
end = len(input)
if lastSpace > since { // rm trailing spaces it ends with 'foo:whatever '
end = lastSpace
} else if since < nextLastSpace { // rm starting spaces it ends with ' foo:whatever'
begin = nextLastSpace
}
kvs = append(kvs, string(input[begin:end]))
}
return
}