aboutsummaryrefslogtreecommitdiffstats
path: root/railties/test
diff options
context:
space:
mode:
authorJamis Buck <jamis@37signals.com>2005-06-22 11:18:01 +0000
committerJamis Buck <jamis@37signals.com>2005-06-22 11:18:01 +0000
commitf69f3848727362648e1b44a2450d0f89dce32bb2 (patch)
treedbeceaf04e1c3db4c8eaf0b595ff128634af9c13 /railties/test
parent053cb22c17b42bdd4bf60a96fbe73df332430556 (diff)
downloadrails-f69f3848727362648e1b44a2450d0f89dce32bb2.tar.gz
rails-f69f3848727362648e1b44a2450d0f89dce32bb2.tar.bz2
rails-f69f3848727362648e1b44a2450d0f89dce32bb2.zip
Refactored dispatch.fcgi. Added unit tests for dispatch.fcgi. Added trap to recognize HUP as a graceful termination command.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1479 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/test')
-rw-r--r--railties/test/fcgi_dispatcher_test.rb96
-rw-r--r--railties/test/mocks/dispatcher.rb11
-rw-r--r--railties/test/mocks/fcgi.rb12
3 files changed, 119 insertions, 0 deletions
diff --git a/railties/test/fcgi_dispatcher_test.rb b/railties/test/fcgi_dispatcher_test.rb
new file mode 100644
index 0000000000..3aeb447fa1
--- /dev/null
+++ b/railties/test/fcgi_dispatcher_test.rb
@@ -0,0 +1,96 @@
+$:.unshift File.dirname(__FILE__) + "/mocks"
+
+require 'test/unit'
+require 'stringio'
+
+if !defined?(RailsFCGIHandler)
+ RAILS_ROOT = File.dirname(__FILE__)
+ load File.dirname(__FILE__) + "/../dispatches/dispatch.fcgi"
+end
+
+class RailsFCGIHandler
+ attr_reader :exit_code
+ attr_accessor :thread
+
+ def trap(signal, handler, &block)
+ handler ||= block
+ (@signal_handlers ||= Hash.new)[signal] = handler
+ end
+
+ def exit(code=0)
+ @exit_code = code
+ (thread || Thread.current).exit
+ end
+
+ def send_signal(which)
+ @signal_handlers[which].call
+ end
+end
+
+class RailsFCGIHandlerTest < Test::Unit::TestCase
+ def setup
+ @log = StringIO.new
+ @handler = RailsFCGIHandler.new(@log)
+ FCGI.time_to_sleep = nil
+ FCGI.raise_exception = nil
+ Dispatcher.time_to_sleep = nil
+ Dispatcher.raise_exception = nil
+ end
+
+ def test_uninterrupted_processing
+ @handler.process!
+ assert_nil @handler.exit_code
+ assert !@handler.please_exit_at_your_earliest_convenience
+ assert !@handler.i_am_currently_processing_a_request
+ end
+
+ %w(HUP USR1).each do |signal|
+ define_method("test_interrupted_via_#{signal}_when_not_in_request") do
+ FCGI.time_to_sleep = 1
+ @handler.thread = Thread.new { @handler.process! }
+ sleep 0.1 # let the thread get started
+ @handler.send_signal(signal)
+ @handler.thread.join
+ assert_equal 0, @handler.exit_code
+ assert !@handler.please_exit_at_your_earliest_convenience
+ assert !@handler.i_am_currently_processing_a_request
+ end
+
+ define_method("test_interrupted_via_#{signal}_when_in_request") do
+ Dispatcher.time_to_sleep = 1
+ @handler.thread = Thread.new { @handler.process! }
+ sleep 0.1 # let the thread get started
+ @handler.send_signal(signal)
+ @handler.thread.join
+ assert_nil @handler.exit_code
+ assert @handler.please_exit_at_your_earliest_convenience
+ assert !@handler.i_am_currently_processing_a_request
+ end
+ end
+
+ %w(RuntimeError SignalException).each do |exception|
+ define_method("test_#{exception}_in_fcgi") do
+ FCGI.raise_exception = Object.const_get(exception)
+ @handler.process!
+ assert_match %r{Dispatcher failed to catch}, @log.string
+ case exception
+ when "RuntimeError"
+ assert_match %r{almost killed}, @log.string
+ when "SignalException"
+ assert_match %r{\d killed}, @log.string
+ end
+ end
+
+ define_method("test_#{exception}_in_dispatcher") do
+ Dispatcher.raise_exception = Object.const_get(exception)
+ @handler.process!
+ assert_match %r{Dispatcher failed to catch}, @log.string
+ case exception
+ when "RuntimeError"
+ assert_no_match %r{killed}, @log.string
+ when "SignalException"
+ assert_match %r{\d killed}, @log.string
+ end
+ end
+ end
+end
diff --git a/railties/test/mocks/dispatcher.rb b/railties/test/mocks/dispatcher.rb
new file mode 100644
index 0000000000..9ca6b609c6
--- /dev/null
+++ b/railties/test/mocks/dispatcher.rb
@@ -0,0 +1,11 @@
+class Dispatcher
+ class <<self
+ attr_accessor :time_to_sleep
+ attr_accessor :raise_exception
+
+ def dispatch(cgi)
+ sleep(time_to_sleep || 0)
+ raise raise_exception, "Something died" if raise_exception
+ end
+ end
+end
diff --git a/railties/test/mocks/fcgi.rb b/railties/test/mocks/fcgi.rb
new file mode 100644
index 0000000000..071b8e1848
--- /dev/null
+++ b/railties/test/mocks/fcgi.rb
@@ -0,0 +1,12 @@
+class FCGI
+ class << self
+ attr_accessor :time_to_sleep
+ attr_accessor :raise_exception
+
+ def each_cgi
+ sleep(time_to_sleep || 0)
+ raise raise_exception, "Something died" if raise_exception
+ yield "mock cgi value"
+ end
+ end
+end