写在前面
基于覆盖率对go编译器进行Fuzzing测试。承接上一部分模型训练,基于Fuzzing测试的结果来选用种子输入模型生成更多的testcase。
遇到的主要问题:
- 理解何为测试“编译器的覆盖率”
被测对象是编译器,而非测试代码,测试编译器覆盖率其实就是测试编译器源码的覆盖率–>测试标准包的覆盖率–>通过coverpkg参数来解决
参考官网上的这一部分:
How can I request coverage instrumentation for all imported packages mentioned in my go.mod file - 初始testcase为不含main函数代码,所以要测覆盖率需要解决生成可执行exe文件的问题
- 想法一:
使用工具自动生成main函数调用testcase中的函数执行 —> gotests
问题:gotests可以生成样例,但是还需要自动编写输入值
解决办法:再使用GoFuzz自动生成数据结构的随机值
问题:testcase具体情况不同,使用GoFuzz又要手动编写代码
失败 - 想法二:
编写一个空的main函数与testcase一起编译,生成可执行exe文件
问题:不存在调用关系的两个go文件是否可以一起编译?
解决办法:两个文件都声明为package main
,即可一起编译
问题:执行main函数时,没有执行到的testcase里的包是否会计算到覆盖率?
解决办法:测试不同的testcase,发现覆盖率不一样,说明会计算到
解决!
以下为我的具体实验步骤。
基本概念
- Fuzzing: 模糊测试(fuzz testing, fuzzing)是一种软件测试技术。 其核心思想是將自动或半自动生成的随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏。 模糊测试常常用于检测软件或计算机系统的安全漏洞。
步骤
一、准备工作
- 安装go编译器并配置环境变量
从源码开始安装go编译器 - 安装gcc或者clang
或者 set the environment variable CGO_ENABLED=0 before running all.bash or make.bash.
二、编写测试脚本
- 创建空的hello.go文件
# hello.go
package main
func main(){}
- 按条读取origin_data.json里的每一条数据
- 处理每一条数据,主要还是按照官网里这一处的步骤。但是需要将第一步修改为获取所有的库,而不是非标准库。且将最终的覆盖率结果输入到result.txt
因此我的最终执行代码为:
$ go list -f '{{.ImportPath}}' -deps . | paste -sd "," > pkgs.txt
$ go build -o myprogram.exe -coverpkg=`cat pkgs.txt` .
$ mkdir somedata
$ GOCOVERDIR=somedata ./myprogram.exe
$ go tool covdata percent -i=somedata > result.txt
- 按照每一条数据的覆盖率进行分析并排序
注:此处需改进,目前只是按照覆盖率之和进行排序