fluentd のプラグインのテストで、他のoutputも利用するタイプのプラグインはどうテストするのかなあと思ってしらべてみた。@tagomoris さんの out_forest はちゃんとテストが存在したのでそれを読む事に。
https://github.com/tagomoris/fluent-plugin-forest/blob/master/test/plugin/test_out_forest.rb#L416
まず fluentd のプラグインのテストの書き方から理解していないので理解しなければ、と 公式ドキュメント を読むと:
Please see Fluentd’s source code for details.
うっ、はい…
まず前準備に Fluent::Test.setup を呼ばないといけないっぽい。これ、engine.rb に書いてある所為でgrepしないと見つからなかった…
これは Fluent::Engine をつくりなおして now, now= メソッドをなんか stub しているっぽい。テストケース毎に呼び直してリセットとかなのかな。
Output プラグインのテストでは、Fluent::Test::OutputTestDriver をつかうといいぽい。
なので、
- OutputTestDriver.new にテストしたい output プラグインのクラスをわたして、Fluent::Test::Base#configure に設定を文字列でわたす。書式は fluentd.conf のフォーマットと一緒。type 宣言等はいらない
- これでテスト対象プラグインのクラスのインスタンスが driver.instance につくられる。
- OutputTestDriver は InputTestDriver を継承していてそれは TestDriver を継承している。ややこい。
- driver.run にブロックつきで渡すと output plugin の #start と #shutdown をそれぞれ yield 前後によしなにやってくれる。なので emit とかの処理は run の中でやるべき。
- TestDriver#run で #start, shutdown をやっている
- driver.emit を呼ぶ事で output plugin の #emit が呼ばれる。この時、EventStream や output chain などがいい感じにつくられる。便利。
- OutputTestDriver.new は第二引数で emit 時の tag を指定できる。
- driver.tag= (writer) も定義されてるのでそれで置き換える事も可能。
- それで plugin の emit は実行されるはずなので、外部モジュールの状態を調べたりすればよい
で、他の output plugin をよんでいるかは:
- ふつうにダミーのOutput プラグインをよばせてそいつの状態をしらべる
- タグをかえて Engine.emit とかしている場合は driver.emits が利用できる。配列にemitしたのがつっこまれてるのでそれを見る。
- InputTestDriver#run で engine の emit_stream メソッドをおきかえているようです。
- note: OutputTestDriver は前述の通り InputTestDriver を継承しているよ
ざっとこんな感じか。もうこれが何してるかだいたい分かるようになった、やった!
https://github.com/tagomoris/fluent-plugin-forest/blob/master/test/plugin/test_out_forest.rb#L416
誰かの参考になれば幸いです。
(fluentd v10 のコード構成、ファイル名とモジュール・クラス名が剥離してるので git grep が手放せないね…)