嘿,猫头虎博主在这里!今天,我们来聊聊Go生态中的一个激动人心的进展 — Fuzzing技术的Beta测试。对于热爱深入探索和挖掘技术细节的你,这将是一个不可错过的话题!
2021年6月3日,Katie Hockman和Jay Conrod宣布,Go语言原生Fuzzing技术已经准备好进行Beta测试。Fuzzing是一种自动化测试方法,通过不断变化程序输入来发现潜在的问题,例如panic或bug。这种半随机的数据变异能够揭示现有单元测试可能错过的新代码覆盖区域,并发现那些通常不易察觉的边缘案例bug。由于Fuzzing能够触及这些边缘案例,它对于发现安全漏洞和漏洞尤其有价值。
首先,你需要按照以下步骤安装并运行:
$ go install golang.org/dl/gotip@latest
$ gotip download
这会从master分支构建Go工具链。完成后,gotip
命令可以替代go
命令使用。现在,你可以运行如下命令:
$ gotip test -fuzz=Fuzz
Fuzz测试必须在*_test.go
文件中作为函数FuzzXxx
形式存在。该函数必须传递一个*testing.F
参数,类似于TestXxx
函数中传递的*testing.T
参数。
以下是针对net/url包的Fuzz测试示例:
//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文档。
这是一个仍处于Beta阶段的新功能,因此你应该预期会遇到一些bug和功能不完整的情况。可以通过查看标有“fuzz”标签的问题跟踪器来了解现有的bug和缺失功能。
请注意,Fuzzing在运行时可能会消耗大量内存,并可能影响你的机器性能。go test -fuzz
默认在并行的$GOMAXPROCS
进程中运行Fuzzing。你可以通过显式设置go test
的-parallel
标志来降低Fuzzing时使用的
进程数量。如果想获取更多信息,可以运行gotip help testflag
阅读go test
命令的文档。
同时要注意,Fuzzing引擎在运行时会将扩展测试覆盖范围的值写入$GOCACHE/fuzz
目录下的Fuzz缓存。目前对Fuzz缓存中可写入的文件数量或总字节数没有限制,因此它可能占用大量存储空间(例如几GB)。你可以通过运行gotip clean -fuzzcache
来清除Fuzz缓存。
该功能将从Go 1.18版本开始提供。
如果你遇到任何问题或对功能有任何建议,请提交问题。
对于该功能的讨论和一般反馈,你也可以参与Gophers Slack中的#fuzzing频道。
祝你Fuzzing愉快!
知识点 | 说明 |
---|---|
Fuzzing技术 | 自动化测试方法,用于发现潜在的panic或bug |
Beta测试 | Go原生Fuzzing技术的测试阶段 |
Fuzz测试编写 | 需在*_test.go文件中作为FuzzXxx函数存在 |
资源消耗 | Fuzzing可能消耗大量内存和存储空间 |
Go版本支持 | 从Go 1.18版本开始提供 |