この記事は、大江戸Ruby会議06で発表した Docker時代の分散RSpec環境の作り方 // Speaker Deck の補足です。
何人かに質問されたことや、良いことばかりじゃなくて現状存在している課題について補足として、ここで書かせてもらいます。
まず、良く質問されたのがテストケースの分割方法です。
テストケースの分割は、現状とても雑にやってます。
まず、featureスペックのファイルだけをリストアップして適当にシャッフルして詰めます。
その後で、他のテストケースを順番に詰める、という感じです。
多少、無駄ではあるんですが、前のテスト結果のプロファイルの収集と詰めるロジックを書くのをサボっても、現状大分早くできたので、とりあえず作りを簡単にする方を優先しました。
課題の中で最も大きな問題は、ログが見辛いという点です。
ECSはログを準リアルタイムで確認するのが、かなり難しいという問題があります。
現在は、syslogログドライバーを利用してpapertrailというログ収集サービスにTLSで直接送り込んでます。
コミット毎に別の識別子を付与する様にしているので、概ね確認はできるし、エスケープシーケンスによる色分けも出来るのですが、並列で実行している結果全てが同じ識別子で出力されるので、結構見辛いです。
一応、最終的な出力で落ちたテストの情報は、CircleCI上にJUnit Formatterの結果として表示されることはされるので、最低限の出力は出る様になってますが。
一応、並列実行の一つ一つレベルで識別子を付与してログの検索結果を独立させることは可能なのですが、ECSのログドライバーのconfigを変更するには現状でtask definitionレベルで変更する必要があります。
そうするとCI実行毎にregister_task_definition
というAPIを並列数分叩く必要があり、APIリクエストのスロットルに引っかかる可能性があります。
また、ECSで使われているDockerのバージョンとECSの基本的なストレージドライバーであるdevice mapperの扱いにバグがある様で、同時にイメージDL処理が走るとストレージドライバーレベルでエラーになる可能性があり、コンテナの起動に失敗する可能性が上がる、という問題があって今はそういう形にしていません。
その他の課題としては、テストをキックした側でコマンドがキャンセルされて中断されたとしても、キャンセル命令をECS側まで届けることが難しいという点です。
これはCLIとしてwrapbox gemを実行した際にシグナルハンドルを定義して、タスクのキャンセルAPIを叩きにいく様にすれば可能だと思いますが、gemの複雑さが増すので、ここも無駄を承知で元がキャンセルされても、コンテナ時代は普通に終わるまで実行が継続される様になってます。