pumactlテスト用ヘルパーメソッドの整理とポート・パス変数の統一
pumactlを用いた統合テストのインターフェースが整理され、設定ファイルベースのテストが容易になりました。これに伴い、バインディングとコントロール用のポート・パス変数の命名も統一されています。
背景
統合テストでpumactlを使用する際、CLI引数ベースの設定は set_pumactl_args メソッドで対応できましたが、設定ファイルベースのテストには対応するヘルパーが存在しませんでした。また、@bind_path、@control_tcp_port などの変数名が統一されておらず、テストコード全体での可読性に課題がありました。
これらの問題に対処するため、#3881 では設定ファイル用のヘルパーメソッド追加と変数名の統一が行われています。
技術的な変更
設定ファイル用ヘルパーの追加
test/helpers/integration.rb に set_pumactl_config メソッドが追加されました。このメソッドは設定ファイル内でpumactlの接続情報を設定する際に使用します。
使用例(変更前):
@control_tcp_port = UniquePort.call
config = <<~RUBY
activate_control_app 'tcp://#{HOST}:#{control_tcp_port}', { auth_token: '#{TOKEN}' }
RUBY
使用例(変更後):
config = <<~RUBY
#{set_pumactl_config}
RUBY
set_pumactl_config は内部で activate_control_app の呼び出しを生成し、ポート割り当ても自動的に行います。これにより、個々のテストでポート管理を行う必要がなくなりました。
ポート・パス変数の統一
バインディングとコントロール用の変数名が統一されています。
変更内容:
# 変更前
@bind_path = tmp_path('.sock')
@control_path = nil
@control_tcp_port = nil
# 変更後
@bind_path = nil
@bind_port = nil
@control_path = nil
@control_port = nil
@tcp_port は @bind_port に、@control_tcp_port は @control_port に統一されました。また、@bind_path の初期化が nil に変更され、必要に応じて動的に設定される方式になっています。
この変更に伴い、テストファイル全体で変数参照が更新されています。
# 変更前
_stdin, curl_stdout, _stderr, curl_wait_thread = Open3.popen3({ 'LC_ALL' => 'C' }, "curl http://#{HOST}:#{@tcp_port}/sleep10")
# 変更後
_stdin, curl_stdout, _stderr, curl_wait_thread = Open3.popen3({ 'LC_ALL' => 'C' }, "curl http://#{HOST}:#{@bind_port}/sleep10")
teardownロジックの改善
test/helpers/integration.rb の teardown メソッドで、サーバー停止処理の条件分岐が明確化されました。
変更後:
def teardown
if @server && !@server_stopped
if @control_port && Puma::IS_WINDOWS
cli_pumactl 'halt'
elsif @pid && !Puma::IS_WINDOWS
stop_server signal: :INT
elsif Puma::IS_WINDOWS
flunk 'Windows must use Puma::ControlCLI to shut down!'
end
end
# ...
end
Windows環境では必ずpumactlを使用してサーバーを停止する必要があり、それ以外の手段が使われた場合は flunk でテストを失敗させる仕組みが追加されています。これにより、プラットフォーム固有の制約が明示的になりました。
その他の細かな修正
ファイル書き込みの簡略化:
# 変更前
File.open(@bind_path, mode: 'wb') { |f| f.puts 'pre existing' }
# 変更後
File.binwrite bind_path, 'pre existing'
nil比較の改善:
# 変更前
assert nil != Process.getpgid(@server.pid)
# 変更後
refute_nil Process.getpgid(@server.pid)
変数初期化の追加:
def skip_if(*engs, suffix: '', bt: caller)
skip_msg = nil # 追加
engs.each do |eng|
skip_msg = case eng
# ...
else nil # false → nil に変更
end
skip(skip_msg, bt) if skip_msg
end
end
skip_msg を明示的に初期化することで、変数スコープの曖昧さが解消されています。
設計判断
既存の set_pumactl_args に対応する形での追加 という方針が採用されました。CLI引数ベースのテストと設定ファイルベースのテストで、同じ命名パターンのヘルパーメソッドを提供することで、テストコードの一貫性が保たれています。
変数名の統一では、bind と control という接続の種類を接頭辞とし、port と path で接続方式を明示する命名規則が確立されました。この規則により、テストコード全体で変数の役割が明確になり、誤用のリスクが低減されています。
Windows環境でのサーバー停止処理の制約を flunk で明示的にエラーとして扱う判断も注目に値します。プラットフォーム固有の制約をテストの失敗として可視化することで、開発者が誤った方法でテストを書くことを防いでいます。
まとめ
本PRは、pumactlを使用する統合テストのインターフェースを整理し、設定ファイルベースのテストを容易にする変更です。set_pumactl_config の追加により、個々のテストでポート管理を行う必要がなくなり、変数名の統一によってテストコード全体の可読性が向上しています。Windows環境での制約を明示的にエラー化する判断も、プラットフォーム固有の問題を早期に発見できる仕組みとして機能します。