概要
テスト自動化において、テスト対象のWebサーバや、バックエンドのDBサーバを一時的に立てて利用することがあります。例えばDockerコンテナとしてサーバプロセスを起動し、リクエストを送信してテストを実行するといった場合です。
サーバプロセス起動を指示してから、サーバプロセスがTCP Portで待ち受けリクエストを処理できるようになるまでにはタイムラグがあり、即座にリクエストを送信すると接続失敗してしまいます。
本稿ではそのような場合にサーバプロセスが待ち受け開始するまでを待つ方法を紹介します。
MySQLサーバを待つ
MySQLの場合は mysqladmin ping を使うとサーバへの接続確認ができるので、それを使います。
$ mysqladmin ping -hホスト名 --silent
mysqladmin: connect to server at 'ホスト名' failed
error: 'Access denied for user 'root'@'接続元IPアドレス' (using password: NO)'
$ echo $?
0
このように戻り値が0であることを確認すれば待ち受けをしていると判定できます(認証エラーが表示されていても、TCP接続ができていれば0が返ります)。
シェルスクリプトのワンライナーでポーリングして待つなら、
while ! mysqladmin ping -hホスト名 --silent; do sleep 1; done
のようにするとよいでしょう。mysqladminコマンドはMySQLの公式のDockerコンテナにも同梱されているので手軽に使えます。
Jenkinsでの利用例を Advanced Usage with Scripted Pipeline > Running "sidecar" containers に記載しているので興味ある方は参照して下さい。
PostgreSQLサーバを待つ
PostgreSQLの場合はpg_isreadyコマンドが利用できます。使い方は簡単です:
$ pg_isready -h ホスト名
ホスト名:5432 - accepting connections
$ echo $?
0
戻り値が0であれば接続成功しています。シェルスクリプトでポーリングして待つ方法は MySQL の場合と同様なので省略します。
一般のTCPサーバを待つ
netcat utilityのポートスキャンの機能を利用できます。
nc -z ホスト名 ポート番号
例えば
$ nc -z qiita.com 443
Connection to qiita.com port 443 [tcp/https] succeeded!
$ echo $?
0
のように戻り値が0であれば接続成功しています。
まとめ
テスト自動化においては、事前条件の保証ができていないと安定的にテストを実行し続けることができません。本稿ではサーバの待ち受けが開始されていることを保証する方法を紹介しました。