分散システムのテストを自動化する

複数のプロセスが相互に連携して動くシステムのテストを自動化したい。

普通に書くとプロセスを起動したあと終了するまで待ってしまうので、複数のプロセスを同時に起動できなくて困ります。&を付けてバックグラウンドで起動させると、後で終了させたとき、まず ps aux | grepしてPIDを調べて、シグナルを飛ばして、しばらくポーリングして本当に終了するまで待つ、なんてことになって面倒です。
それから起動してからしばらくは初期化処理が走っているので、標準出力に「started」と表示されるまで待ちたかったりします。


そのあたりをうまく扱うためのライブラリを書いてみました。↓こんな感じで自動化できます。

#!/usr/bin/env ruby
require 'chukan'
include Chukan

srv = spawn("server -arg1 -arg2")  # 'server' コマンドを '-arg1 -arg2' 引数付きで実行する
srv.stdout_join("started")         # server の標準出力に "started" と出力されるまで待つ

cli = spawn("client -arg1 -arg2")  # 'client' コマンドを引数を付けて実行する
src.stdout_join("connected")       # server の 標準出力に "connected" と出力されるまで待つ

cli.kill                           # client に SIGKILL シグナルを飛ばす
srv.stderr_join(/disconnected/)    # 標準エラー出力と、正規表現も使える

srv.stdin.write "status\n"         # server の標準入力に "status\n" と書き込む
srv.stdout_join("done")            # server の標準出力に "done" と出力するまで待つ

if srv.stdout.read =~ /^client:/   # server の標準出力を読み込んで正規表現でマッチ
  puts "** TEST FAILED **"         # テストを書くのに便利!
end


※2009-1-26 追記:
gemでインストールできるようになりました。

gem install chukan

ソースコードはgithubにあります:http://github.com/frsyuki/chukan


※2009-03-19 追記:
プロセスをリモートホスト上で実行できるようになりました:

require 'chukan'
include Chukan

mac = remote("mymac.local")        # sshでリモートホストにログインしてコマンドを実行
                                   # 鍵が暗号化されているときはssh-agentをあらかじめ起動しておく
mac.cd("work/myproject")           # "work/myproject" ディレクトリで実行する

linux = remote("192.168.10.2", "myname", ".id_rsa_linux")
                                   # オプションでユーザー名と鍵のパスを指定可能

cli_on_mac   = mac.spawn("client -arg1")   # spawnでコマンドを実行
cli_on_linux = linux.spawn("client -arg1")

cli_on_mac.stdout_join("started")  # シグナルとI/O関連はリモートプロセスでも使える

※2010-11-22 追記:

単体テストの記述が簡単になりました!>Chukanにユニットテストフレームワークを統合してみる