GO言語のプログラミングエッセンスを読んで:Go Fuzzingを試してみた その2
今朝は5時から開発開始です。
かみさんのウッドデッキ補修は、昨日は天気予報で雨と言っていたので2度塗りを諦めていました。でも、雨は降りませんでした。天気予報、がんばれ!
さて、昨日から始めたGo Fuzzingを使ってログ分析ツールのテストをしてみる試みです。
昨日ビルドエラーになっていたのは
% go test -fuzztime 20s -fuzz FuzzSetting
# github.com/twsnmp/TWLogAIAN
./processor.go:810:11: fmt.Errorf format %s has arg b.processConf.Extractor of wrong type *github.com/vjeantet/grok.Grok
FAIL github.com/twsnmp/TWLogAIAN [build failed]
というものです。ソースコードの場所をみると
return fmt.Errorf("invalid extractor type %s", b.processConf.Extractor)
ポインターを%sで文字列にしようとしていることを指摘していました。
実行するためのビルドだと指摘されないエラーですが、テストのためのビルドが厳格なのかもしれません。本題のFuzzingテストではありませんが一つバグが見つかりました。
ここを修正 (%s->%v)してFuzzingテストを実行すると面白いほど問題が見つかりました。私は見つかった問題を解決するのが趣味なのかもしれません。
例えば、
% go test -fuzztime 10s -fuzz FuzzSetting
fuzz: elapsed: 0s, gathering baseline coverage: 0/11 completed
fuzz: elapsed: 0s, gathering baseline coverage: 11/11 completed, now fuzzing with 6 workers
fuzz: minimizing 40-byte failing input file
fuzz: elapsed: 0s, minimizing
--- FAIL: FuzzSetting (0.07s)
--- FAIL: FuzzSetting (0.00s)
setting_test.go:17: failed td='0A0=0' k='0A0=0' s='' rmap=map[A0=0:A0=%{NUMBER:A0}]
のようなエラーです。0A0=0のような入力は期待していないのですが、間違った結果を返しています。
テストコードのチェックも厳密にやりすぎるとFuzzingテストをパスするようにはできません。テストのチェックもFuzzingしたほうがちょうどよいかもしれません。
テストした関数の仕様は
文字列の中に" a=10 "のようなパターンがあればa=10:a=%{NUMBER:a}というデータをmapに設定する
文字列の中に" b=test "のようなパターンがあればb=test:b=%{WORD:b}というデータをmapに設定する
というものです。ログの中からデータを抽出するために使います。
最終的に、
のように修正して
func FuzzSetting(f *testing.F) {
f.Add(" number=1 ")
f.Add(" string=hehehe ")
f.Fuzz(func(t *testing.T, td string) {
rmap := make(map[string]string)
findSplunkPat(td, rmap)
if len(rmap) > 0 {
for k := range rmap {
if !strings.Contains(td, k) {
t.Fatalf("failed td='%s' k='%s' rmap=%+v", td, k, rmap)
}
}
}
})
}
のようなテストを実行すると
% go test -fuzztime 20s -fuzz FuzzSetting
fuzz: elapsed: 0s, gathering baseline coverage: 0/117 completed
fuzz: elapsed: 0s, gathering baseline coverage: 117/117 completed, now fuzzing with 6 workers
fuzz: elapsed: 3s, execs: 70662 (23548/sec), new interesting: 8 (total: 125)
fuzz: elapsed: 6s, execs: 187539 (38955/sec), new interesting: 12 (total: 129)
fuzz: elapsed: 9s, execs: 330331 (47612/sec), new interesting: 18 (total: 135)
fuzz: elapsed: 12s, execs: 490155 (53274/sec), new interesting: 22 (total: 139)
fuzz: elapsed: 15s, execs: 602263 (37365/sec), new interesting: 31 (total: 148)
fuzz: elapsed: 18s, execs: 711206 (36319/sec), new interesting: 32 (total: 149)
fuzz: elapsed: 21s, execs: 794372 (27723/sec), new interesting: 39 (total: 156)
fuzz: elapsed: 21s, execs: 794372 (0/sec), new interesting: 39 (total: 156)
PASS
ok github.com/twsnmp/TWLogAIAN 21.357s
のように20秒間に80万パターン実行して問題なしになりました。
品質がアップしたような気がします。
明日に続く
いいなと思ったら応援しよう!
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。
ソフトウェアのマニュアルをnoteの記事で提供しています。
サポートによりnoteの運営にも貢献できるのでよろしくお願います。