piontに失敗行きます

最近、外出先failpiontに関するいくつかの情報を学んだし、今それを共有したいと思います。

FailPiontは、自動テストの障害をシミュレートするために使用されます

自動テストは、多くの場合、いくつかの障害状態をシミュレートするために、その後、障害が私たちの考えに基づいて適切に実行するかどうかを、この場合には、当社の手続きをテストする必要があります。いくつかの障害がテストコードのシミュレーションに簡単ですが、このような切断されたネットワーク・インタフェース・トラフィックなどのいくつかの比較的くんダンは、同様のオーバーランがあります。そして、FailPiont外に従事するための素晴らしい神があります。

 Etcdが行わgofail  https://github.com/etcd-io/gofail

gofailが使用されています

FUNC someFunc()文字列{ 
	// gofailます。var SomeFuncString文字列
	// // failpointがトリガされたときに、これはSomeFuncStringcalledさ
	SomeFuncString返す// 
	リターン"default"を
}

  シミュレートされた失敗のコードを書くために、コードはコメントアウト。我々は、コマンドを有効にgofail実行をテストする場合、コードはそうなっています

FUNC someFunc()文字列{ 
	場合vSomeFuncString、__fpErr:= __fp_SomeFuncString.Acquire()。__fpErr ==ゼロ{__fp_SomeFuncString.Release()を延期します。SomeFuncString、__fpTypeOK:= vSomeFuncString(ストリング)。もし__ fpTypeOK {goto文__badTypeSomeFuncString}!
		 failpointがトリガされたとき//これがSomeFuncStringcalledされる
		 リターンSomeFuncStringを。__badTypeSomeFuncString:__fp_SomeFuncString.BadType(vSomeFuncString、 "文字列"); }。
	"default"を返します
}

  生成されたファイルもあります

// GOFAILによって生成されます。編集しないでください。

パッケージfail_pointの

インポート"github.com/etcd-io/gofail/runtime" 

のvar __fp_SomeFuncString * runtime.Failpoint = runtime.NewFailpoint( "fail_point"、 "SomeFuncString")

  その後、我々はテストコードを書きます

FUNC Test_someFunc(T * testing.T){ 
	// /ユーザ/ EDZ /ドキュメントは/ dev /メトリック/ SRC / fail_point / 
	gofail.Enable( "fail_point / SomeFuncString"、 `リターン( "SomeFuncStringは")`)
	gofail.Disableを延期します( "fail_point / SomeFuncString")
	試験:= []構造体{ 
		名文字列が
		文字列を必要
	} { 
		{名: "パス"は、望む: "SomeFuncStringを"}、
	} 
	ため_、TT =レンジテスト{ 
		t.Run(TT。名前、FUNC(T * testing.T){ 
			得た場合:= someFunc(); = tt.want {ました!
				t.Errorf( "someFunc()=%vを、%vをしたい"、tt.wantを得ました)
			} 
		})
	} 
}

  

渡された、いくつかのテストを実行します。

 

そして生成されたコードの可読性が悪い。しかし、このgofailはまた、このようなコメントの存在がエラーを見つけることは容易ではないとして、いくつかの欠点を持っています。

これらの問題を解決するには、pingcap同社はgofail ==「failpiontのアップグレード版を作りました

このようなコードはfailpiontです

FUNC pingCapFail()(文字列、failpoint.Value){ 
	failpoint.Inject( "failpoint名"、FUNC(ヴァルfailpoint.Value){ 
		failpoint.Return( "ユニットテスト"、ヴァル)
	})
	リターン"成功"、ゼロ
} 

pingCapFail1 FUNC()文字列{ 
	failpoint.Inject( "failpoint-NAME1"、FUNC(){ 
		failpoint.Return( "ユニットテスト")
	})
	リターン"成功" 
} 

pingCapFail2(CTX context.Context)FUNC(文字列、failpoint .VALUE){ 
	failpoint.InjectContext(CTX、 "failpoint-NAME2"、FUNC(ヴァルfailpoint.Value){ 
		failpoint.Return( "ユニットテスト"、ヴァル)
	})
	リターン"成功"、ゼロ
}

  

私たちは、達成するために、アノテーションを使用しての欠点を回避failpiont、参照するだけでなく、コードの実行に影響を与えるためにいくつかのコードを挿入することができます。

これは、テストでは複数の同時テストケースを可能にするさまざまなユースケースといくつかの障害がトリガされる、いくつかの障害を無視します。

 

実行failpoint-CTLを有効にするには、コマンドを有効にします

コードはこのようになっています。この時間

FUNC pingCapFail()(文字列、failpoint.Value){ 
	もしヴァル、OK:= failpoint.Eval(_curpkg _( "failpoint名")); OK { 
		リターン"ユニットテスト"、ヴァル
	} 
	リターン"成功"、ゼロ
} 

pingCapFail1()文字列{FUNC 
	_場合、OK:= failpoint.Eval(_curpkg _( "failpoint-NAME1"))。OK { 
		リターン"ユニットテスト" 
	} 
	戻り"成功" 
} 

pingCapFail2(CTX context.Context)FUNC(文字列、failpoint.Value){ 
	もしヴァル、OK:= failpoint.EvalContext(CTX、_curpkg _( "failpoint-NAME2") ); OK { 
		リターン「ユニットテスト」、ヴァル
	} 
	リターン「成功」、ゼロ
}

  コードの可読性も高いときにこれは見ることができます。

その後、我々はいくつかのテストコードを書きます

FUNC Test_pingCapFail(T * testing.T){ 
	テスト:= []構造体{ 
		名文字列
		の文字列が欲しい
		failpoint.Valueをwant1 
	} { 
		{名: "pingCapFail"は、望む: "ユニットテスト"、want1:5} 
	} 
	failpointを。イネーブル( "fail_point / failpoint名"、 "リターン(5)")
	_、TTのために:=範囲のテスト{ 
		t.Run(tt.name、FUNC(T * testing.T){ 
			得た、GOT1:= pingCapFail( )
			得た場合!= tt.want { 
				t.Errorf( "pingCapFail()だ=%V、欲しい%V"、だ、tt.want)
			} 
			であれば!reflect.DeepEqual(GOT1、tt.want1){ 
				t.Errorf ( "pingCapFail()GOT1 =%V、%Vを望む"、GOT1、tt.want1)
			} 
		})
	} 
}

FUNC Test_pingCapFail1(T * testing.T){ 
	テスト:= []構造体{ 
		名文字列が
		文字列を必要
	} { 
		{名: "pingCapFail1"、欲しい: "ユニットテスト"}、
	} 
	failpoint.Enable(「fail_point / failpoint-NAME1 」、 "リターン(5)")
	_、TTのために:=範囲のテスト{ 
		t.Run(tt.name、FUNC(T * testing.T){ 
			得た場合:!= pingCapFail1は(); = tt.wantを{ました
				t.Errorf( "pingCapFail1()=%のV、%Vを望む"、得、tt.want)
			} 
		})
	} 
} 

Test_pingCapFail2 FUNC(T * testing.T){ 
	型引数構造体{ 
		CTX context.Context 
	} 
	C = &gin.Context {} 
	failPoints:=マップ[文字列]のstruct {} { 
		"A":{}、
		"B":{}、
		// "fail_point / failpoint-NAME2":{} 
	} 
	CTX:= failpoint.WithHook(C、FUNC(CTX context.Context、fpname列)BOOL { 
		= failPoints [fpname:実測値_、 ] //一部だけfailpointsを可能にします。
		見つかっ返す
	})

	のテストを:= []構造体{ 
		name文字列の
		引数の引数は
		文字列たい
		failpoint.Value want1を
	} { 
		{ "pingCapFail2"、引数{CTX}、 "成功"、nilを}、
	} 
	failpoint .ENABLE( "fail_point / failpoint-NAME2"、 "戻る(5)")
	_、TT用:=レンジテスト{ 
		{t.Run(tt.name、FUNC(T * testing.T)
			= pingCapFail2:得、GOT1 (tt.args.ctx)
			!= tt.want {得た場合
				t.Errorf( "pingCapFail2は、()=%vを得、%vをしたい"、tt.wantだ)
			} 
			!reflect.DeepEqual(GOT1、tt.want1){もし
				t.Errorf(「pingCapFail2()GOT1 =%V 、」%vをしたい、GOT1、tt.want1)
			} 
		})
	} 
}

  

 

それを実行し、テスト。

私は便利になりたい、あなたに感謝します。

 

おすすめ

転載: www.cnblogs.com/13579net/p/10937279.html
おすすめ