1

Golang failpoint工具

 2 years ago
source link: http://rivenzoo.github.io/2020/04/25/Golang-failpoint%E5%B7%A5%E5%85%B7/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Golang failpoint工具

2020-04-25

字数统计: 442字

  |   阅读时长≈ 1分钟

failpoint是用于测试时注入错误的工具。
来源是BSD系统的failpoint功能,已有的go语言实现有etcd的gofail。

它与gofail的区别是用标记函数代替了注释,标记函数的好处在于IDE可以识别并且编译时可以进行语法检查。

package main

import "github.com/pingcap/failpoint"

func main() {
failpoint.Inject("testPanic", func() {
panic("failpoint triggerd")
})
}

打开错误failpoint-ctl enable
关闭failpoint-ctl disable

enable和disable命令对应code目录下面的两个功能模块

  • rewriter
  • restorer

rewriter

Rewriter遍历目录,根据文件名过滤掉非go文件和rewrite之后生成的文件。
parse文件的import,过滤没有import标记函数包的文件

file, err := parser.ParseFile(fset, path, nil, parser.ImportsOnly)

对所有函数定义进行rewrite

fn, ok := decl.(*ast.FuncDecl)
r.rewriteFuncDecl(fn)

rewrite使用了递归,覆盖了所有可能出现注入错误的语句。
实际需要修改的是表达式*ast.ExprStmt,并且是包函数调用*ast.SelectorExpr

exprRewriter, found := exprRewriters[expr.Sel.Name]
if !found {
break
}
rewritten, stmt, err := exprRewriter(r, call)
if err != nil {
return err
}

标记函数对应的修改函数的映射放在exprRewriters这个map
修改函数构造一个新的stmt替换掉原来的语句,再输出到原文件,修改就完成了。
除了修改原文件,rewriter会生成一个binding文件和原文件的备份,备份文件用于disable的时候来恢复原文件。

restorer

restore没有直接把备份文件rename为原文件,而是把生成的文件跟备份文件做了一次diff,然后把patch加到备份文件上,这样做是为了把生成之后对新文件的修改应用到备份文件上,避免用户disable之后修改丢失。

  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!

扫一扫,分享到微信

微信分享二维码

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK