Test::TCPでgearman workerのテストを書く
この項、必ず追記を参照のこと。
Gearmanを使ったジョブの処理を書いていて、
- gearmandを起動
- workerプロセスを起動
- clientがジョブを投げ、先に起動したworkerがそれを処理
- 返ってきた結果を検証
- テスト終了時には、gearmand/workerをシャットダウン
ってのを全部いっぺんにできないかなーってんで、Test::TCPでやってみました。workerプロセスはlistenする必要がないので、
no warnings 'redefine'; local *Test::TCP::wait_port = sub {};
とかしちゃってるところが「ヒャー」って感じですが、まあいいかな、と。。。他にいい方法があったら教えてください!!1
use strict; use warnings; use Test::TCP; use Test::More; use Gearman::Worker; use Gearman::Client; test_tcp( client => sub { my $port = shift; no warnings 'redefine'; local *Test::TCP::wait_port = sub {}; test_tcp( client => sub { my $client = Gearman::Client->new; $client->job_servers("127.0.0.1:$port"); my $result = $client->do_task('test'); is $$result, 1; }, server => sub { my $worker = Gearman::Worker->new; $worker->job_servers("127.0.0.1:$port"); # 例のため適当なsubrefを登録しているが、実際には、 # テストを行うfunctionをregisterする $worker->register_function(test => sub { 1 }); $worker->work while 1; }, ) }, server => sub { my $port = shift; exec 'gearmand', '-p', $port; } ); done_testing;
追記
id:tokuhiromにツッコミいただきました(「それ Proc::Guard 0.04 でできるよっていう話」)。ありがとうございます!!1
というわけで、Proc::Guardを使って以下のようにすればより良いです。
use strict; use warnings; use Test::TCP; use Test::More; use Proc::Guard 0.04 qw/proc_guard/; use Gearman::Worker; use Gearman::Client; test_tcp( client => sub { my $port = shift; my $worker_guard = proc_guard(sub { my $worker = Gearman::Worker->new; $worker->job_servers("127.0.0.1:$port"); # 例のため適当なsubrefを登録しているが、実際には、 # テストを行うfunctionをregisterする $worker->register_function(test => sub { 1 }); $worker->work while 1; }); my $client = Gearman::Client->new; $client->job_servers("127.0.0.1:$port"); my $result = $client->do_task('test'); is $$result, 1; }, server => sub { my $port = shift; exec 'gearmand', '-p', $port; } ); done_testing;