DiffDaily

Deep & Concise - OSS変更の定点観測

[Rails] ActionCableのテストで発生するRACK_ENV環境変数のリーク問題を修正

rails/rails

背景

ActionCableのClientTest実行時に、LeakCheckerが「Environment leak detected: Added variables: RACK_ENV」というエラーを報告していました。この問題は、Pumaサーバーが起動時にRACK_ENV環境変数を設定するものの、テスト終了後にクリーンアップされていなかったことが原因でした。

環境変数のリークは、テスト間の独立性を損ない、予期しない副作用を引き起こす可能性があります。特にCI環境では、このような問題がテストの信頼性を低下させる要因となります。

技術的な変更内容

修正前の問題

with_puma_serverメソッドは、Pumaサーバーをセットアップして起動していましたが、ensureブロックで環境変数の復元処理が実装されていませんでした。Pumaは起動時に自動的にRACK_ENVを設定するため、テスト実行後もこの値が環境に残り続けていました。

修正後の実装

環境変数の保存と復元を適切に行うよう、以下の変更が加えられました。

def with_puma_server(rack_app = ActionCable.server, port = 3099)
  original_rack_env = ENV["RACK_ENV"]

  opts = { min_threads: 1, max_threads: 4 }
  server = if Puma::Const::PUMA_VERSION >= "6"
    # ... サーバーセットアップ処理
  end

  begin
    # ... サーバー起動処理
  ensure
    begin
      server.stop
      server.binder.close
    rescue IOError
      server.binder.close
    end

    ENV["RACK_ENV"] = original_rack_env
  end
end

実装のポイント

  1. メソッド開始時の状態保存: with_puma_serverの冒頭でoriginal_rack_env = ENV["RACK_ENV"]として、元のRACK_ENVの値(存在しない場合はnil)を保存します。

  2. ensureブロックでの復元: サーバーのクリーンアップ処理の後、ENV["RACK_ENV"] = original_rack_envで元の状態に戻します。これにより、テスト前にRACK_ENVが設定されていなかった場合はnilに戻り、環境変数自体が削除されます。

  3. 既存のエラーハンドリングとの統合: この変更は、既存のIOErrorハンドリングを維持しつつ、環境変数の復元を追加する形で実装されています。

影響範囲

この修正により、ActionCableのClientTestは環境変数のリークなしに実行できるようになります。テストの独立性が向上し、CI環境での安定性も改善されます。

変更はactioncable/test/client_test.rbのテストヘルパーメソッドのみに限定されており、プロダクションコードには影響しません。