模糊测试已经准备好进入Beta测试

Fuzzing is Beta Ready - 模糊测试已经准备好进入Beta测试

https://go.dev/blog/fuzz-beta

Katie Hockman and Jay Conrod 3 June 2021

2021年6月3日

​ 我们很高兴地宣布,原生模糊测试已经准备好在tip上进行beta测试了!

​ Fuzzing是一种自动化测试,它持续操纵程序的输入,以发现panic或bug等问题。这些半随机的数据突变可以发现现有单元测试可能错过的新的代码覆盖率,并发现边缘用例的bug,否则这些bug就不会被注意到。由于 fuzzing 可以接触到这些边缘用例,所以模糊测试对于发现安全漏洞和漏洞特别有价值。

​ 关于该功能的更多细节,请参见 golang.org/s/draft-fuzzing-design

开始使用

​ 要开始使用,您可以运行以下命令

1
2
$ go install golang.org/dl/gotip@latest
$ gotip download

​ 这将从主分支构建Go工具链。运行这个命令后,gotip可以作为go命令的直接替代者。现在您可以运行如下命令

1
$ gotip test -fuzz=Fuzz

编写模糊测试

​ 一个模糊测试必须在*_test.go文件中以FuzzXxx的形式成为一个函数。这个函数必须被传递一个*testing.F参数,就像TestXxx函数被传递*testing.T参数一样。

​ 以下是一个测试net/url包行为的模糊测试的示例。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//go:build go1.18
// +build go1.18

package fuzz

import (
    "net/url"
    "reflect"
    "testing"
)

func FuzzParseQuery(f *testing.F) {
    f.Add("x=1&y=2")
    f.Fuzz(func(t *testing.T, queryStr string) {
        query, err := url.ParseQuery(queryStr)
        if err != nil {
            t.Skip()
        }
        queryStr2 := query.Encode()
        query2, err := url.ParseQuery(queryStr2)
        if err != nil {
            t.Fatalf("ParseQuery failed to decode a valid encoded query %s: %v", queryStr2, err)
        }
        if !reflect.DeepEqual(query, query2) {
            t.Errorf("ParseQuery gave different query after being encoded\nbefore: %v\nafter: %v", query, query2)
        }
    })
}

​ 您可以在pkg.go.dev阅读更多关于fuzzing的内容,包括Go的fuzzing概述新的testing.F类型的godoc

期望

​ 这是一项仍处于测试阶段的新功能,因此您应该会遇到一些错误和不完整的功能集。请查看问题追踪器中标有 “fuzz”的问题,以了解现有错误和缺失功能的最新情况。

​ 请注意,fuzzing会消耗大量内存,在运行时可能会影响您的机器性能。 go test -fuzz默认为在$GOMAXPROCS进程中并行运行fuzzing。您可以通过在go test中明确设置-parallel标志来降低模糊处理时使用的进程数。如果您想了解更多信息,可以运行 gotip help testflag 阅读 go test 命令的文档。

​ 还要注意的是,模糊测试引擎在运行时,会将扩大测试范围的数值写入$GOCACHE/fuzz的模糊缓存目录中。目前对写入模糊缓存的文件数量或总字节数没有限制,所以它可能会占用大量的存储空间(即几个GB)。您可以通过运行 gotip clean -fuzzcache 来清除 fuzz 缓存。

下一步是什么?

​ 这项功能将在Go 1.18中开始使用。

​ 如果您遇到任何问题或有任何关于该功能的想法,请提交问题

​ 关于该功能的讨论和一般反馈,您也可以参与Gophers Slack的#fuzzing频道

​ Happy fuzzing!