golang在GitHub Actions中使用内置模糊测试功能的插件库go-fuzz-action的使用
Golang在GitHub Actions中使用内置模糊测试功能的插件库go-fuzz-action的使用
概述
go-fuzz-action是一个用于在GitHub Actions中运行Go内置模糊测试的插件。它支持Go 1.18及以上版本的内置模糊测试功能。
输入参数
-
fuzz-time
[必需]: 模糊测试目标迭代持续时间,使用time.Duration
格式(例如1h30s
)。对应go test
命令的-fuzztime
标志。确保这个时间小于你的job/workflow超时时间。 -
packages
[可选]: 在这些包上运行模糊测试。对应go test
命令的[packages]
输入。- 默认值:
.
- 默认值:
-
fuzz-regexp
[可选]: 运行匹配正则表达式的模糊测试。对应go test
命令的-fuzz
标志。- 默认值:
Fuzz
- 默认值:
-
fuzz-minimize-time
[可选]: 模糊最小化持续时间,使用time.Duration
格式(例如1h30s
)。对应go test
命令的-fuzzminimizetime
标志。- 默认值:
10s
- 默认值:
-
go-version
[可选]: 用于模糊测试的Go版本。这将传递给actions/setup-go@v3
。- 默认值:
1.18
- 默认值:
返回结果
- SUCCESS: 如果在
fuzz-time
输入约束内你的模糊测试没有引发失败。 - FAILURE: 如果在
fuzz-time
输入约束内你的模糊测试引发了失败。- 工作流运行日志将包含如何下载(使用GitHub CLI)失败的种子语料到本地机器进行修复的说明。
使用示例
基本用法
name: Go fuzz test
on:
push:
pull_request:
jobs:
fuzz-test:
name: Fuzz test
runs-on: ubuntu-latest
steps:
- uses: jidicula/go-fuzz-action@v1.1.0
with:
fuzz-time: 30s
测试仓库中的所有包
name: Go fuzz test
on:
push:
pull_request:
jobs:
fuzz-test:
name: Fuzz test
runs-on: ubuntu-latest
steps:
- uses: jidicula/go-fuzz-action@v1.1.0
with:
packages: './...'
fuzz-time: 30s
更长的最小化时间
name: Go fuzz test
on:
push:
pull_request:
jobs:
fuzz-test:
name: Fuzz test
runs-on: ubuntu-latest
steps:
- uses: jidicula/go-fuzz-action@v1.1.0
with:
packages: './...'
fuzz-time: 30s
fuzz-minimize-time: 1m
使用不同的正则表达式匹配模糊测试
name: Go fuzz test
on:
push:
pull_request:
jobs:
fuzz-test:
name: Fuzz test
runs-on: ubuntu-latest
steps:
- uses: jidicula/go-fuzz-action@main
with:
packages: './...'
fuzz-time: 30s
fuzz-minimize-time: 1m
fuzz-regexp: OtherFuzzRegexp
⚠️注意: 这个Action没有在windows
GitHub Actions runners上测试过! 使用windows
runner操作系统需自行承担风险!
更多关于golang在GitHub Actions中使用内置模糊测试功能的插件库go-fuzz-action的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang在GitHub Actions中使用内置模糊测试功能的插件库go-fuzz-action的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在GitHub Actions中使用go-fuzz-action进行模糊测试
Go 1.18引入了内置的模糊测试功能,而go-fuzz-action是一个GitHub Action插件,可以方便地在CI/CD流程中运行Go的模糊测试。下面我将详细介绍如何使用这个工具。
基本使用
首先,你需要在项目中创建一个模糊测试。例如,创建一个fuzz_test.go
文件:
package mypackage
import (
"testing"
"unicode/utf8"
)
func FuzzReverse(f *testing.F) {
testcases := []string{"Hello, world", " ", "!12345"}
for _, tc := range testcases {
f.Add(tc) // 使用f.Add添加种子语料库
}
f.Fuzz(func(t *testing.T, orig string) {
rev := Reverse(orig)
doubleRev := Reverse(rev)
if orig != doubleRev {
t.Errorf("Before: %q, after: %q", orig, doubleRev)
}
if utf8.ValidString(orig) && !utf8.ValidString(rev) {
t.Errorf("Reverse produced invalid UTF-8 string %q", rev)
}
})
}
func Reverse(s string) string {
b := []byte(s)
for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
b[i], b[j] = b[j], b[i]
}
return string(b)
}
GitHub Actions配置
在.github/workflows/fuzz.yml
中添加以下配置:
name: Fuzz Test
on: [push, pull_request]
jobs:
fuzz:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.20' # 确保使用支持模糊测试的Go版本
- name: Run Fuzz Tests
uses: devfuzz/github-action@v1
with:
working-directory: ./path/to/package # 可选,指定包含模糊测试的目录
fuzz-test: FuzzReverse # 指定要运行的模糊测试函数
fuzz-time: 30s # 每个模糊测试运行的时间
race: true # 启用数据竞争检测
高级配置选项
go-fuzz-action提供了多个配置选项:
- name: Run Fuzz Tests
uses: devfuzz/github-action@v1
with:
working-directory: ./test/fuzz
fuzz-test: FuzzParse,FuzzEncode # 可以指定多个测试
fuzz-time: 1m
test-timeout: 10m # 整体测试超时
race: true
cover: true # 生成覆盖率报告
verbose: true # 详细输出
keep-artifacts: true # 保留崩溃用例
build-tags: integration # 构建标签
处理崩溃用例
当模糊测试发现崩溃时,go-fuzz-action会自动保存崩溃用例作为工作流产物。你可以下载这些用例并在本地重现问题:
# 下载崩溃用例后
go test -run=FuzzReverse/testdata/fuzz/FuzzReverse/<crash-file>
最佳实践
- 种子语料库:使用
f.Add()
添加有代表性的种子输入 - 测试时间:根据项目复杂度设置合理的
fuzz-time
,通常30s-5分钟 - 并行测试:可以在GitHub Actions矩阵中并行运行多个模糊测试
- 定期运行:建议在schedule触发器中也运行模糊测试
完整示例
这是一个完整的GitHub Actions工作流示例,包含并行测试和覆盖率收集:
name: Advanced Fuzz Testing
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * 0' # 每周日运行
jobs:
fuzz:
strategy:
matrix:
test: [FuzzReverse, FuzzParse, FuzzEncode]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.20'
- name: Run Fuzz Test
uses: devfuzz/github-action@v1
with:
fuzz-test: ${{ matrix.test }}
fuzz-time: 1m
race: true
cover: true
keep-artifacts: true
- name: Upload coverage
uses: actions/upload-artifact@v3
if: always()
with:
name: coverage-${{ matrix.test }}
path: ./coverage.out
- name: Upload crashes
uses: actions/upload-artifact@v3
if: failure()
with:
name: crashes-${{ matrix.test }}
path: ./testdata/fuzz/${{ matrix.test }}
通过这种方式,你可以将模糊测试集成到你的CI/CD流程中,持续发现代码中的潜在问题。