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