Cloud RunでTestCafeを動かしたところ、Chromeやnodeのプロセスが残ってしまうことがありました。
SeleniumではなくTestCafeなのはプロジェクトの方針
いままでは、ブラウザを用いたテストというとSeleniumを使ってきましたが、今回はTestCafeです。既に他のプロジェクトで使っているので、あわせます。

商用製品の一部を公開したものですが、Seleniumのように、ブラウザのバージョンにあったドライバーを入れたり、ライブラリのバージョンや依存関係に悩んだりということはありません。Chromeなどのブラウザを用意して、npmでtestcafeを入れれば準備完了です。
Testが終わってもメモリが使われている
Webサイトが正常に稼働しているかどうか、定期的にテストする。
こんな目的なら、VMインスタンスを使うよりもCloud Scheduler+Cloud Runでしょう。
ということでコンテナ化して手元のPCのDocker Desktopで動かしてみたところ、Testが終わってもメモリの使用量が多いままという現象が発生しました。
プロセスの状態を見てみました。
Test中:
sh-4.2# pstree -l
server-+-chrome-+-2*[cat]
| |-chrome---chrome---4*[{chrome}]
| |-chrome---chrome---18*[{chrome}]
| |-chrome---9*[{chrome}]
| `-21*[{chrome}]
|-sh---node-+-main-+-node---6*[{node}]
| | `-10*[{main}]
| `-6*[{node}]
`-6*[{server}]
sh-4.2#
Test終了後:
sh-4.2# pstree -l
server-+-2*[cat]
|-6*[chrome]
|-node
`-6*[{server}]
sh-4.2#
serverはCloud Runに必要なhttp serverですのでいいのですが、Chromeとnodeのプロセスが残っています。
tiniでPID 1の問題を解決する
「ゾンビプロセスは誰が弔うの?」
コンテナはプロセス+αと考えると気にしないところでしょうが、TestCafeだとブラウザを別プロセスとして立ち上げるわけですから、ゾンビプロセスの処理が必要です。ここまで絞り込めれば、ググってもそれなりの記事が見つかります。

GCPのドキュメントにも記載がありました。

問題2の解決策として2と3があげられていますが、Cloud Runなので解決策2は使えませんし、docker run –init も使えません。AWS ECSだと、initProcessEnabledというタスク定義パラメータがあるのですが。
そこで、解決策3で示されているようにtiniを使うことにし、READMEに従ってDockerfileに手を入れます。
ゾンビもきれいさっぱり
tiniを入れてTestを動かした後の様子が、こちら。
sh-4.2# pstree -l
tini---server---6*[{server}]
sh-4.2#
Chromeもnodeもいなくなりました。
シグナル処理はグレイスフルシャットダウンの実現で必要ですが、ゾンビプロセスの後始末が必要かと言われると、initプロセスにおまかせ!というケースも多そうです。そう考えると、保険の意味でも、tiniのようなコンテナ専用のinitシステムを入れておくのはよさそうです。


コメント