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

1 回复

更多关于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>

最佳实践

  1. 种子语料库:使用f.Add()添加有代表性的种子输入
  2. 测试时间:根据项目复杂度设置合理的fuzz-time,通常30s-5分钟
  3. 并行测试:可以在GitHub Actions矩阵中并行运行多个模糊测试
  4. 定期运行:建议在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流程中,持续发现代码中的潜在问题。

回到顶部