aboutsummaryrefslogtreecommitdiffstats
path: root/railties/test/fcgi_dispatcher_test.rb
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2007-09-23 11:20:25 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2007-09-23 11:20:25 +0000
commit547447ad2abf72f6f5eb57a76b1a830feca34d90 (patch)
tree9fd1c0e044e8873b46e22561fedb57405e8e9d73 /railties/test/fcgi_dispatcher_test.rb
parent4e3ed5bc44f6cd20c9e353ab63fd24b92a7942be (diff)
downloadrails-547447ad2abf72f6f5eb57a76b1a830feca34d90.tar.gz
rails-547447ad2abf72f6f5eb57a76b1a830feca34d90.tar.bz2
rails-547447ad2abf72f6f5eb57a76b1a830feca34d90.zip
RailsFCGIHandler tests. Closes #9630.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7593 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/test/fcgi_dispatcher_test.rb')
-rw-r--r--railties/test/fcgi_dispatcher_test.rb296
1 files changed, 148 insertions, 148 deletions
diff --git a/railties/test/fcgi_dispatcher_test.rb b/railties/test/fcgi_dispatcher_test.rb
index 37bf4c8641..7949cb6525 100644
--- a/railties/test/fcgi_dispatcher_test.rb
+++ b/railties/test/fcgi_dispatcher_test.rb
@@ -1,92 +1,78 @@
require File.dirname(__FILE__) + "/abstract_unit"
-begin # rescue LoadError
+uses_mocha 'fcgi dispatcher tests' do
-require_library_or_gem 'mocha'
-
-$:.unshift File.dirname(__FILE__) + "/mocks"
-
-require 'stringio'
-
-# Stubs
require 'fcgi_handler'
-require 'routes'
-require 'stubbed_kernel'
-
-class RailsFCGIHandler
- attr_reader :exit_code
- attr_reader :reloaded
- attr_accessor :thread
- attr_reader :gc_runs
-
- 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(which)
- end
-
- alias_method :old_run_gc!, :run_gc!
- def run_gc!
- @gc_runs ||= 0
- @gc_runs += 1
- old_run_gc!
- end
-end
+module ActionController; module Routing; module Routes; end 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_process_restart
- @handler.stubs(:when_ready).returns(:restart)
-
- @handler.expects(:close_connection)
+ cgi = mock
+ FCGI.stubs(:each_cgi).yields(cgi)
+
+ @handler.expects(:process_request).once
+ @handler.expects(:dispatcher_error).never
+
+ @handler.expects(:when_ready).returns(:restart)
+ @handler.expects(:close_connection).with(cgi)
+ @handler.expects(:reload!).never
@handler.expects(:restart!)
+
@handler.process!
end
-
+
def test_process_exit
- @handler.stubs(:when_ready).returns(:exit)
-
- @handler.expects(:close_connection)
+ cgi = mock
+ FCGI.stubs(:each_cgi).yields(cgi)
+
+ @handler.expects(:process_request).once
+ @handler.expects(:dispatcher_error).never
+
+ @handler.expects(:when_ready).returns(:exit)
+ @handler.expects(:close_connection).with(cgi)
+ @handler.expects(:reload!).never
+ @handler.expects(:restart!).never
+
@handler.process!
end
-
+
def test_process_with_system_exit_exception
- @handler.stubs(:process_request).raises(SystemExit)
-
- @handler.expects(:dispatcher_log).with(:info, "terminated by explicit exit")
+ cgi = mock
+ FCGI.stubs(:each_cgi).yields(cgi)
+
+ @handler.expects(:process_request).once.raises(SystemExit)
+ @handler.stubs(:dispatcher_log)
+ @handler.expects(:dispatcher_log).with(:info, regexp_matches(/^stopping/))
+ @handler.expects(:dispatcher_error).never
+
+ @handler.expects(:when_ready).never
+ @handler.expects(:close_connection).never
+ @handler.expects(:reload!).never
+ @handler.expects(:restart!).never
+
@handler.process!
end
-
+
def test_restart_handler
@handler.expects(:dispatcher_log).with(:info, "asked to restart ASAP")
-
+
@handler.send(:restart_handler, nil)
assert_equal :restart, @handler.when_ready
end
-
+
def test_install_signal_handler_should_log_on_bad_signal
@handler.stubs(:trap).raises(ArgumentError)
@handler.expects(:dispatcher_log).with(:warn, "Ignoring unsupported signal CHEESECAKE.")
@handler.send(:install_signal_handler, "CHEESECAKE", nil)
end
-
+
def test_reload
@handler.expects(:restore!)
@handler.expects(:dispatcher_log).with(:info, "reloaded")
@@ -94,8 +80,8 @@ class RailsFCGIHandlerTest < Test::Unit::TestCase
@handler.send(:reload!)
assert_nil @handler.when_ready
end
-
-
+
+
def test_reload_runs_gc_when_gc_request_period_set
@handler.expects(:run_gc!)
@handler.expects(:restore!)
@@ -103,19 +89,20 @@ class RailsFCGIHandlerTest < Test::Unit::TestCase
@handler.gc_request_period = 10
@handler.send(:reload!)
end
-
+
def test_reload_doesnt_run_gc_if_gc_request_period_isnt_set
@handler.expects(:run_gc!).never
@handler.expects(:restore!)
@handler.expects(:dispatcher_log).with(:info, "reloaded")
@handler.send(:reload!)
end
-
+
def test_restart!
@handler.expects(:dispatcher_log).with(:info, "restarted")
- assert_equal true, @handler.send(:restart!), "Exec wasn't run"
+ @handler.expects(:exec).returns('restarted')
+ assert_equal 'restarted', @handler.send(:restart!)
end
-
+
def test_restore!
$".expects(:replace)
Dispatcher.expects(:reset_application!)
@@ -124,105 +111,129 @@ class RailsFCGIHandlerTest < Test::Unit::TestCase
end
def test_uninterrupted_processing
+ cgi = mock
+ FCGI.expects(:each_cgi).yields(cgi)
+ @handler.expects(:process_request).with(cgi)
+
@handler.process!
- assert_nil @handler.exit_code
+
assert_nil @handler.when_ready
end
+end
+
+
+class RailsFCGIHandlerSignalsTest < Test::Unit::TestCase
+ def setup
+ @log = StringIO.new
+ @handler = RailsFCGIHandler.new(@log)
+ end
def test_interrupted_via_HUP_when_not_in_request
- @handler.expects(:reload!)
- FCGI.time_to_sleep = 1
- @handler.thread = Thread.new { @handler.process! }
- sleep 0.1 # let the thread get started
- @handler.send_signal("HUP")
- @handler.thread.join
- assert_nil @handler.exit_code
+ cgi = mock
+ FCGI.expects(:each_cgi).once.yields(cgi)
+ @handler.expects(:gc_countdown).returns { Process.kill 'HUP', $$ }
+
+ @handler.expects(:reload!).once
+ @handler.expects(:close_connection).never
+ @handler.expects(:exit).never
+
+ @handler.process!
assert_equal :reload, @handler.when_ready
end
def test_interrupted_via_HUP_when_in_request
- @handler.expects(:reload!)
-
- Dispatcher.time_to_sleep = 1
- @handler.thread = Thread.new { @handler.process! }
- sleep 0.1 # let the thread get started
- @handler.send_signal("HUP")
- @handler.thread.join
- assert_nil @handler.exit_code
+ cgi = mock
+ FCGI.expects(:each_cgi).once.yields(cgi)
+ Dispatcher.expects(:dispatch).with(cgi).returns { Process.kill 'HUP', $$ }
+
+ @handler.expects(:reload!).once
+ @handler.expects(:close_connection).never
+ @handler.expects(:exit).never
+
+ @handler.process!
assert_equal :reload, @handler.when_ready
end
def test_interrupted_via_USR1_when_not_in_request
- FCGI.time_to_sleep = 1
- @handler.thread = Thread.new { @handler.process! }
- sleep 0.1 # let the thread get started
- @handler.send_signal("USR1")
- @handler.thread.join
- assert_nil @handler.exit_code
- assert_equal :exit, @handler.when_ready
+ cgi = mock
+ FCGI.expects(:each_cgi).once.yields(cgi)
+ @handler.expects(:gc_countdown).returns { Process.kill 'USR1', $$ }
+ @handler.expects(:exit_handler).never
+
+ @handler.expects(:reload!).never
+ @handler.expects(:close_connection).with(cgi).once
+ @handler.expects(:exit).never
+
+ @handler.process!
+ assert_nil @handler.when_ready
end
def test_interrupted_via_USR1_when_in_request
- Dispatcher.time_to_sleep = 1
- @handler.thread = Thread.new { @handler.process! }
- sleep 0.1 # let the thread get started
- @handler.send_signal("USR1")
- @handler.thread.join
- assert_nil @handler.exit_code
+ cgi = mock
+ FCGI.expects(:each_cgi).once.yields(cgi)
+ Dispatcher.expects(:dispatch).with(cgi).returns { Process.kill 'USR1', $$ }
+
+ @handler.expects(:reload!).never
+ @handler.expects(:close_connection).with(cgi).once
+ @handler.expects(:exit).never
+
+ @handler.process!
assert_equal :exit, @handler.when_ready
end
-
+
def test_interrupted_via_TERM
- Dispatcher.time_to_sleep = 1
- @handler.thread = Thread.new { @handler.process! }
- sleep 0.1 # let the thread get started
- @handler.send_signal("TERM")
- @handler.thread.join
- assert_equal 0, @handler.exit_code
+ cgi = mock
+ FCGI.expects(:each_cgi).once.yields(cgi)
+ Dispatcher.expects(:dispatch).with(cgi).returns { Process.kill 'TERM', $$ }
+
+ @handler.expects(:reload!).never
+ @handler.expects(:close_connection).never
+
+ @handler.process!
assert_nil @handler.when_ready
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{^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{^killed}, @log.string
- end
- end
+ def test_runtime_exception_in_fcgi
+ error = RuntimeError.new('foo')
+ FCGI.expects(:each_cgi).times(2).raises(error)
+ @handler.expects(:dispatcher_error).with(error, regexp_matches(/^retrying/))
+ @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
+ @handler.process!
+ end
+
+ def test_runtime_error_in_dispatcher
+ cgi = mock
+ error = RuntimeError.new('foo')
+ FCGI.expects(:each_cgi).once.yields(cgi)
+ Dispatcher.expects(:dispatch).once.with(cgi).raises(error)
+ @handler.expects(:dispatcher_error).with(error, regexp_matches(/^unhandled/))
+ @handler.process!
+ end
+
+ def test_signal_exception_in_fcgi
+ error = SignalException.new('USR2')
+ FCGI.expects(:each_cgi).once.raises(error)
+ @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
+ @handler.process!
+ end
+
+ def test_signal_exception_in_dispatcher
+ cgi = mock
+ error = SignalException.new('USR2')
+ FCGI.expects(:each_cgi).once.yields(cgi)
+ Dispatcher.expects(:dispatch).once.with(cgi).raises(error)
+ @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
+ @handler.process!
end
end
+
class RailsFCGIHandlerPeriodicGCTest < Test::Unit::TestCase
def setup
@log = StringIO.new
- FCGI.time_to_sleep = nil
- FCGI.raise_exception = nil
- FCGI.each_cgi_count = nil
- Dispatcher.time_to_sleep = nil
- Dispatcher.raise_exception = nil
- Dispatcher.dispatch_hook = nil
end
def teardown
- FCGI.each_cgi_count = nil
- Dispatcher.dispatch_hook = nil
GC.enable
end
@@ -235,31 +246,20 @@ class RailsFCGIHandlerPeriodicGCTest < Test::Unit::TestCase
end
def test_periodic_gc
- Dispatcher.dispatch_hook = lambda do |cgi|
- # When GC is disabled, GC.enable enables and returns true.
- assert_equal true, GC.enable
- GC.disable
- end
-
@handler = RailsFCGIHandler.new(@log, 10)
assert_equal 10, @handler.gc_request_period
- FCGI.each_cgi_count = 1
- @handler.process!
- assert_equal 1, @handler.gc_runs
- FCGI.each_cgi_count = 10
- @handler.process!
- assert_equal 3, @handler.gc_runs
+ cgi = mock
+ FCGI.expects(:each_cgi).times(10).yields(cgi)
+ Dispatcher.expects(:dispatch).times(10).with(cgi)
- FCGI.each_cgi_count = 25
+ @handler.expects(:run_gc!).never
+ 9.times { @handler.process! }
+ @handler.expects(:run_gc!).once
@handler.process!
- assert_equal 6, @handler.gc_runs
- assert_nil @handler.exit_code
assert_nil @handler.when_ready
end
end
-rescue LoadError => e
- $stderr.puts "Skipping dispatcher tests. `gem install mocha` and try again. (#{e})"
-end \ No newline at end of file
+end # uses_mocha