测试是功能上线之前的重要环节。

测试过程中,要尽量覆盖各种场景。故障情况或异常情况下的场景测试,也是必不可少的。

如何模拟故障呢?

在FreeBSD 中, failpoints经常用来模拟故障。

在golang,也有failpoint的实现,就是目前pingcap 公司的开源项目failpoint.

下面介绍golang中的failpoint的实现。

1.安装failpoint工具

cd $GOPATH/src

mkdir -p github.com/pingcap

cd github.com/pingcap

git clone https://github.com/pingcap/failpoint.git

cd failpoint

make
GO111MODULE=on CGO_ENABLED=0 GO111MODULE=on go build -ldflags '-X "github.com/pingcap/failpoint/failpoint-ctl/version.releaseVersion=12f4ac2-dev" -X "github.com/pingcap/failpoint/failpoint-ctl/version.buildTS=2019-11-15 09:41:49" -X "github.com/pingcap/failpoint/failpoint-ctl/version.gitHash=12f4ac2fd11dfc6b2f7018b00bb90f61a5b6b692" -X "github.com/pingcap/failpoint/failpoint-ctl/version.gitBranch=master" -X "github.com/pingcap/failpoint/failpoint-ctl/version.goVersion=go version go1.13 darwin/amd64"' -o bin/failpoint-ctl failpoint-ctl/main.go
failpoint-ctl build successfully :-) !

注意:仔细确认这些步骤。如果搞错,会出现无法转换代码的情况。

编译后,生成可执行文件failpoint-ctl:

ll bin
total 6840
-rwxr-xr-x 1 lanyang staff 3.3M 11 15 17:41 failpoint-ctl

2. 测试代码

代码结构如下:

cd $GOPATH/src

mkdir fp_example

cd fp_example
# tree ./
./
├── fruit
│   └── banana.go
├── main.go
└── util
├── apple.go
└── orange.go

其中,main.go文件内容:

package main

import (
"fmt"
"fp_example/hot_fruit"
"fp_example/fruit"
) func main() { hot_fruit.Apple()
hot_fruit.Orange()
fruit.Banana() fmt.Println("main end")
}

fruit/banana.go:

package fruit

import (
"fmt"
"github.com/pingcap/failpoint"
) func Banana() {
fmt.Println("banana....") failpoint.Inject("bananaPanic", func() {
panic("banana failpoint triggerd")
}) }

注入一个panic。

hot_fruit/apple.go:

package hot_fruit

import (
"fmt"
"github.com/pingcap/failpoint"
) func Apple() {
fmt.Println("apple....") failpoint.Inject("applePanic", func() {
panic("apple failpoint triggerd")
}) }

再次注入一个panic。

hot_fruit/orange.go:

package hot_fruit

import (
"fmt"
"github.com/pingcap/failpoint" )
func Orange() {
fmt.Println("orange....") failpoint.Inject("orangePanic", func() {
panic("orange failpoint triggerd")
}) }

再次注入一个panic。

3. 使用failpoint转换代码

$GOPATH/src/github.com/pingcap/failpoint/bin/failpoint-ctl enable

代码转换之后,看下代码文件结构:

 tree ./
./
├── fruit
│   ├── banana.go
│   ├── banana.go__failpoint_stash__
│   └── binding__failpoint_binding__.go
├── hot_fruit
│   ├── apple.go
│   ├── apple.go__failpoint_stash__
│   ├── binding__failpoint_binding__.go
│   ├── orange.go
│   └── orange.go__failpoint_stash__
├── main.go 2 directories, 10 files

可以看到多了几个文件。

如果执行disable,这些文件又会消失。

$GOPATH/src/github.com/pingcap/failpoint/bin/failpoint-ctl disable

4.编译和执行

使用装换之后的代码,进行编译:

go build -o simple main.go

生成可执行文件simple.

正常执行:

./simple
apple....
orange....
banana....
main end

触发bananaPanic故障执行:

GO_FAILPOINTS="fp_example/fruit/bananaPanic=return(true)" ./simple
apple....
orange....
banana....
panic: banana failpoint triggerd goroutine 1 [running]:
fp_example/fruit.Banana()
/Users/lanyang/workspace/go_projects/src/fp_example/fruit/banana.go:12 +0x10e
main.main()
/Users/lanyang/workspace/go_projects/src/fp_example/main.go:13 +0x2c

其中,fp_example/fruit 是package名称, bananaPanic是注入的故障名称。

触发applePanic故障执行:

GO_FAILPOINTS="fp_example/hot_fruit/applePanic=return(true)" ./simple

apple....
panic: apple failpoint triggerd goroutine 1 [running]:
fp_example/hot_fruit.Apple()
/Users/lanyang/workspace/go_projects/src/fp_example/hot_fruit/apple.go:12 +0x10e
main.main()
/Users/lanyang/workspace/go_projects/src/fp_example/main.go:11 +0x22

触发orangePanic故障执行:

GO_FAILPOINTS="fp_example/hot_fruit/orangePanic=return(true)" ./simple
apple....
orange....
panic: orange failpoint triggerd goroutine 1 [running]:
fp_example/hot_fruit.Orange()
/Users/lanyang/workspace/go_projects/src/fp_example/hot_fruit/orange.go:12 +0x10e
main.main()
/Users/lanyang/workspace/go_projects/src/fp_example/main.go:12 +0x27

5.参考

pingcap/failpoint

Golang Failpoint 的设计与实现

golang 故障模拟工具failpoint的使用的更多相关文章

  1. (转载)分享常用的GoLang包工具

    分享常用的GoLang包工具 包名 链接地址 备注 Machinery异步队列 https://github.com/RichardKnop/machinery Mqtt通信 github.com/e ...

  2. Golang xorm工具,根据数据库自动生成 go 代码

    使用 golang 操作数据库的同学都会遇到一个问题 —— 根据数据表结构创建对应的 struct 模型.因为 golang 的使用首字母控制可见范围,我们经常要设计 struct 字段名和数据库字段 ...

  3. 分享常用的GoLang包工具

    包名 链接地址 备注 Machinery异步队列 https://github.com/RichardKnop/machinery Mqtt通信 github.com/eclipse/paho.mqt ...

  4. golang版本管理工具GO111MODULE

    在go1.11版本前,想要对go语言包进行管理,只能依赖第三方库实现,比如Vendor,GoVendor,GoDep,Dep,Glide等等. 1. 开启GO111MODULE 用环境变量 GO111 ...

  5. Golang开发工具LiteIDE使用方法整理

    安装 参考github的说明 添加GOPATH 创建workspace 创建新文件 运行程序 Liteide中运行程序有两种方式: FR(FileRun)是编译并运行单个文件,可以使用Shift + ...

  6. 初生牛犊不怕虎 golang入坑系列

    读前必读,下面所有内容都是来自这里. 放到这里的目的,就是为了比对一下,哪里的读者多.平心而论,同样的Markdown,博客园排版真心X看,怎么瞅怎么X看.(X := '难' || X :='耐' | ...

  7. golang动态加载原生代码思路

    golang动态加载原生代码思路(非plugin,非so文件.使用mmap形式运行机器码,可释放) 1.用go tool objdump,可以看到任意函数的机器码.汇编指令.偏移.(go源码下面有一个 ...

  8. 使用 dep 配置 golang 开发环境

    概要 golang 的包管理一直没有官方统一的解决方案,因此也产生了很多非官方的包管理工具. 之前我一直使用的 gb(https://getgb.io/) 能够很好的隔开各个 golang 工程,当时 ...

  9. Emacs中多个golang项目的配置方法

    概述 最近使用golang开发项目时, 发现有时需要同时进行多个golang项目. 在这种情况下, 如果把所有的项目都放在 GOPATH 之下, 不仅管理麻烦(因为各个项目需要提交到不同的代码库), ...

随机推荐

  1. RabbitMQ的特点与应用场景(二)

      1.RabbitMQ的主要特点 (1)可靠性:RabbitMQ可通过队列持久化,交换机持久化,消息持久化及ACK回应等机制保证可靠性 (2)支持多种语言与协议:RabbitMQ几乎支持所有的编程语 ...

  2. Linux克隆修改配置文件及IP

    Linux下安装基本的开发软件比较费劲,特别是安装mysql的时候,这时候就需要学会克隆及直接备份base虚拟机了,下次直接打开,修改网卡文件信息就完事. 克隆虚拟机eth0网卡出现的问题解决1:修改 ...

  3. 本地安装mysql脚本

    [root@tianyun ~]# vim mysql_install.sh #!/usr/bin/env bash #mysql install 2 #by tianyun #yum 配置yum源 ...

  4. VMware虚拟机CentOS与宿主机共享目录

    正常情况下,在虚拟机CentOS中安装了vmware-tools后,配置完成共享目录,会自动在/mnt/hgfs下面出现共享目录. 如果该目录为空,并且通过命令:vmware-hgfsclient 的 ...

  5. MNPR--造福人类的人值得被感激

    https://artineering.io/research/MNPR/ https://mnpr.artineering.io https://pdfs.semanticscholar.org/0 ...

  6. Java web中不同浏览器间导出Excel文件名称乱码问题解决方案

    问题描述: 对于不同浏览器存在对中文编码格式问题,从而在导出Excel文件时,中文文件名出现乱码的情况,即在程序中给要导出的文件指定一个中文名字时,在浏览器上出现的下载框中的文件名出现了乱码,解决如下 ...

  7. react-router5.x 的配置及其页面跳转方法和js跳转方法

    https://blog.csdn.net/sinat_37255207/article/details/90745207 上次用react-router 的时候  还是3.x 很久不用 已经到rea ...

  8. CodeForces 839B - Game of the Rows | Codeforces Round #428 (Div. 2)

    血崩- - /* CodeForces 839B - Game of the Rows [ 贪心,分类讨论] | Codeforces Round #428 (Div. 2) 注意 2 7 2 2 2 ...

  9. 【Android-关闭所有Activity】关闭activity之前的所有activity,重启actibity

    Android关闭activity之前的所有activity,重启actibity 直接关闭一个activity之前的所有Activity页面 解决方法:清理activity堆栈 Intent ine ...

  10. mysql数据库的主从同步,实现读写分离

    大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器来处理如此多的数据库连接操作,数据库必然会崩溃,特别 ...