Chapter 13無料公開

複数のランブックをシャッフルして実行する

Ken’ichiro Oyama
Ken’ichiro Oyama
2023.01.06に更新

runnは、複数のランブックをシャッフルして実行できます。

--shuffle

runnコマンドで複数のランブックをシャッフルして実行する場合は --shuffle オプションを使用します。

$ runn run path/to/**/*.yml --shuffle on

また、 --shuffle 12345 のようにシード値を与えることもできます。

runn.RunShuffle

runnをパッケージとしてGoのコードの組み込む場合、 runn.Load の第2引数に渡すオプションとして runn.RunShuffle を指定します。

ctx := context.Background()
opts := []runn.Option{
	runn.T(t),
	runn.RunShuffle(true, time.Now().UnixNano()),
}
o, err := runn.Load("path/to/**/*.yml", opts...)
if err != nil {
	t.Fatal(err)
}
if err := o.RunN(ctx); err != nil {
	t.Fatal(err)
}

[コラム] シャッフルを常に on にしておくと良い理由。シード値を与えるユースケース。

シャッフルを常に on にしておくと良い理由

Goの go test にも --shuffle オプションがあります。runnの --shuffle オプションもGoを参考にしました。

Goのテストでシャッフルを常に有効( on )にしておくと実行順序がシャッフルされるため、必然的に前のテストの結果に依存しているテストを検知できます[1]

同様に、複数のランブックの実行でもシャッフルを常に有効にしておくと、前のランブックの結果に依存しているランブックを検知できます。

シード値を与えるユースケース

シード値を与えるユースケースはどのようなものがあるでしょうか?
1つは「シャッフルした結果の再現」です。同じシード値を与えれば同じシャッフル結果を得ることができます。

筆者が使うもう1つのユースケースは「シャッフルと分割実行の併用」です。

シャッフルと分割実行の併用

前項でシャッフルは常に有効にしたほうが良いと述べました。
一方で、シナリオの数が増えて実行時間が大きくなってくると、実行環境を複数用意して、実行するシナリオを複数のグループに分割して実行したくなります。

複数のランブックをシャッフルしつつ分割して実行する方法はいくつか考えられます。

  1. 複数のランブックをシャッフルしてから分割して、それぞれの実行環境に実行すべきランブックを識別できる情報を共有する。実行環境側で複数のランブックの担当分を実行する。
  2. 分割数を決定して、それぞれの実行環境に分割数とインデックス(分割したグループの何番目を実行するのかの情報)を共有する。実行環境側で複数のランブックを分割してからシャッフルして担当分を実行する。
  3. 分割数とシード値を決定して、それぞれの実行環境にシード値と分割数とインデックスを共有する。実行環境側で複数のランブックをシャッフルしてから分割して担当分を実行する。

3つのどれでも分割して実行するができます。しかし、次のような差異があります。

  • 前処理と実行環境側の処理で考えると、1は、2や3と比べて前処理でもランブックの操作が必要になっています。
  • 分割結果で考えると、2は、1や3と比べてシャッフルの範囲が限定的です(シャッフル前に分割してしまうため)。

このように、シード値を使うことでシャッフルと分割実行を併用する環境が構築しやすいと考えています。

脚注
  1. フューチャー技術ブログのエントリ「Go 1.17のtesting新機能」の「テストをシャッフルすると何が嬉しいのか」の項がとてもわかりやすいです。 ↩︎