Open20

Go 1.17(?)で入るFuzzingについて調べるぞ!

tenntenntenntenn

現在はdev.fuzzブランチで開発が進んでいる。
Goのツールチェインをクローンしてきて以下でビルドできる。
all.bashよりmake.bashの方が早い(テストしないから)。

$ git checkout dev.fuzz
$ cd src
$ ./make.bash
tenntenntenntenn

https://play.golang.org/p/llB7iBL1zSP

Fuzzで始まる関数を作る。引数は*testing.Fにする。

func FuzzHoge(f *testing.F) {
}

f.Addでコーパスのシードを設定する。
Addできるのは、組み込み型(おそらくエラーは除く)、構造体(たぶんフィールドが対応する型の)とBinaryMarshalerインタフェースとBinaryUnmarshalerインタフェースまたはTextMarshalerインタフェースとTextUnmarshalerインタフェースを実装した型。

Addメソッドは可変長引数。

go doc testing.F.Add
package testing // import "testing"

func (f *F) Add(args ...interface{})
    Add will add the arguments to the seed corpus for the fuzz target. This will
    be a no-op if called after or within the Fuzz function. The args must match
    those in the Fuzz function.

f.Fuzzメソッドでテストを実行する。
引数はテスト関数。
テスト関数の引数は第1引数が*testing.Tで残りがFuzzing対象の機能の入力となるもの。
↓の例では、Addメソッドでint型とstring型を指定してるからこの2つの型になっている。

func FuzzHoge(f *testing.F) {
    f.Add(10, "hoge")
    f.Add(-1, "fuga")
    f.Fuzz(func(t *testing.T, n int, s string) {
    })
}

与えたシードを基に入力データをミューテーションしていく。

tenntenntenntenn

go testだけ実行するとf.Addしたシードだけでテストをしてくれる模様。
単純なテストとして実行できるのは良さそう。