9

Heroku は、さまざまな理由でアプリケーションに SIGTERM を送信することがあります。そのため、これが発生した場合に備えて、いくつかのクリーンアップを処理するハンドラーを作成しました。一部のグーグルでは、RSpec でこれをテストする方法に関する回答や例が得られませんでした。基本的なコードは次のとおりです。

Signal.trap('TERM') do  
    cleanup  
end

def cleanup
    puts "doing some cleanup stuff"
    ...
    exit
end

プログラムが SIGTERM を受け取ったときにこのクリーンアップ メソッドが呼び出されることをテストする最良の方法は何ですか?

4

1 に答える 1

6

自殺しろ!RSpec にシグナルを送信しProcess.kill 'TERM', 0、ハンドラーが呼び出されることをテストします。シグナルがトラップされない場合、うまく失敗を報告するのではなく、テストがクラッシュするのは事実ですが、少なくともコードに問題があることがわかります。

例えば:

class SignalHandler
  def self.trap_signals
    Signal.trap('TERM') { term_handler }
  end

  def self.term_handler
    # ...
  end

end

describe SignalHandler do
  describe '#trap_signals' do
    it "traps TERM" do
      # The MRI default TERM handler does not cause RSpec to exit with an error.
      # Use the system default TERM handler instead, which does kill RSpec.
      # If you test a different signal you might not need to do this,
      # or you might need to install a different signal's handler.
      old_signal_handler = Signal.trap 'TERM', 'SYSTEM_DEFAULT'

      SignalHandler.trap_signals
      expect(SignalHandler).to receive(:term_handler).with no_args
      Process.kill 'TERM', 0 # Send the signal to ourself

      # Put the Ruby default signal handler back in case it matters to other tests
      Signal.trap 'TERM', old_signal_handler
    end
  end
end

ハンドラーが呼び出されることをテストしただけですが、ハンドラーの副作用も同様にテストできます。

于 2016-01-31T20:42:08.050 に答える