Eventually
記法
Ginkgo とセットで使われるテストマッチャーの Gomega には
Eventually
という便利な機能があります。
これを使うと、Eventually
に渡した処理が期待する結果を返すか、
あるいは規定秒経過するまで、
与えた処理をリトライさせ続けるテストが書けます。
実行完了まで時間のかかる処理をテストしたい場合に有用です。
By("Checking cluster status")
Eventually(func() bool {
controlPlanes := []string{node1, node2, node3, node4}
workers := []string{node5, node6}
return checkClusterStatus(status, controlPlanes, workers)
}).Should(BeTrue())
タイムアウトを待たずしてEventually
をabortするMatcherとそうでないMatcherがあります
しかし 「Eventually
に渡した処理のアサーションは規定秒必ず待ってくれるんだな〜」と言えるのかというと、そうではないです。
デフォルトで用意されてるマッチャーの中には
MatchMayChangeInTheFuture
というメソッドが実装されているものがあります。
これが実装されているマッチャーは、
MatchMayChangeInTheFuture
のチェックで
これ以上値の変化は起きないだろうと判断した場合、タイムアウトを待たずしてテストをfailします。
具体的には gexec.Command
を使ったときの exitMatcher
がそれです。
これを使うと、
Eventually(session).Should(gexec.Exit())
みたいな感じで Eventually
にコマンドを渡してexecすることができるのですが、
これは -1
以外のステータスコードが返った時点で Eventually
が終了します。
その後はリトライされません。
自分はこのことを知らないまま雰囲気でEventually
を使っていたので「Eventually
に渡した処理が5秒で終わるんだが…?」などと悩み、
20分かかるテストを再実行したり、
実装を読んだりしました。
そしてこの話は普通にドキュメントに書いてありました。
ちゃんとドキュメントを読もう。(自戒)
https://onsi.github.io/gomega/#aborting-eventuallyconsistently