提交 f6339eb1 编写于 作者: J Jeremy Kemper

Thoroughly test the FCGI dispatcher. Closes #5970.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4913 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 4c734530
*SVN* *SVN*
* Thoroughly test the FCGI dispatcher. #5970 [Kevin Clark]
* Remove Dir.chdir in the Webrick DispatchServlet#initialize method. Fix bad path errors when trying to load config/routes.rb. [Rick Olson] * Remove Dir.chdir in the Webrick DispatchServlet#initialize method. Fix bad path errors when trying to load config/routes.rb. [Rick Olson]
* Tighten rescue clauses. #5985 [james@grayproductions.net] * Tighten rescue clauses. #5985 [james@grayproductions.net]
......
...@@ -50,25 +50,7 @@ def process!(provider = FCGI) ...@@ -50,25 +50,7 @@ def process!(provider = FCGI)
run_gc! if gc_request_period run_gc! if gc_request_period
provider.each_cgi do |cgi| process_each_request!(provider)
process_request(cgi)
case when_ready
when :reload
reload!
when :restart
close_connection(cgi)
restart!
when :exit
close_connection(cgi)
break
when :breakpoint
close_connection(cgi)
breakpoint!
end
gc_countdown
end
GC.enable GC.enable
dispatcher_log :info, "terminated gracefully" dispatcher_log :info, "terminated gracefully"
...@@ -87,9 +69,9 @@ def process!(provider = FCGI) ...@@ -87,9 +69,9 @@ def process!(provider = FCGI)
dispatcher_error(fcgi_error, "killed by this error") dispatcher_error(fcgi_error, "killed by this error")
end end
end end
private protected
def logger def logger
@logger ||= Logger.new(@log_file_path) @logger ||= Logger.new(@log_file_path)
end end
...@@ -145,6 +127,28 @@ def breakpoint_handler(signal) ...@@ -145,6 +127,28 @@ def breakpoint_handler(signal)
dispatcher_log :info, "asked to breakpoint ASAP" dispatcher_log :info, "asked to breakpoint ASAP"
@when_ready = :breakpoint @when_ready = :breakpoint
end end
def process_each_request!(provider)
provider.each_cgi do |cgi|
process_request(cgi)
case when_ready
when :reload
reload!
when :restart
close_connection(cgi)
restart!
when :exit
close_connection(cgi)
break
when :breakpoint
close_connection(cgi)
breakpoint!
end
gc_countdown
end
end
def process_request(cgi) def process_request(cgi)
Dispatcher.dispatch(cgi) Dispatcher.dispatch(cgi)
...@@ -204,4 +208,4 @@ def gc_countdown ...@@ -204,4 +208,4 @@ def gc_countdown
def close_connection(cgi) def close_connection(cgi)
cgi.instance_variable_get("@request").finish cgi.instance_variable_get("@request").finish
end end
end end
\ No newline at end of file
$:.unshift File.dirname(__FILE__) + "/../../activesupport/lib"
$:.unshift File.dirname(__FILE__) + "/../../actionpack/lib"
$:.unshift File.dirname(__FILE__) + "/../lib"
$:.unshift File.dirname(__FILE__) + "/../builtin/rails_info"
require 'test/unit'
require 'rubygems'
require 'mocha'
require 'stubba'
# Needed for the class mock delegation
#require File.dirname(__FILE__) + "/../../activesupport/lib/active_support/core_ext/class/attribute_accessors"
if defined?(RAILS_ROOT)
RAILS_ROOT.replace File.dirname(__FILE__)
else
RAILS_ROOT = File.dirname(__FILE__)
end
class Test::Unit::TestCase
# Add stuff here if you need it
end
$:.unshift File.dirname(__FILE__) + "/../lib" require File.dirname(__FILE__) + "/abstract_unit"
$:.unshift File.dirname(__FILE__) + "/mocks" $:.unshift File.dirname(__FILE__) + "/mocks"
require 'test/unit'
require 'stringio' require 'stringio'
require 'fcgi_handler'
RAILS_ROOT = File.dirname(__FILE__) if !defined?(RAILS_ROOT) # Stubs
require 'fcgi_handler'
require 'routes'
require 'stubbed_breakpoint'
require 'stubbed_kernel'
class RailsFCGIHandler class RailsFCGIHandler
attr_reader :exit_code attr_reader :exit_code
...@@ -26,13 +29,8 @@ def exit(code=0) ...@@ -26,13 +29,8 @@ def exit(code=0)
def send_signal(which) def send_signal(which)
@signal_handlers[which].call(which) @signal_handlers[which].call(which)
end end
def restore!
@reloaded = true
end
def reload! def breakpoint
@reloaded = true
end end
alias_method :old_run_gc!, :run_gc! alias_method :old_run_gc!, :run_gc!
...@@ -53,6 +51,102 @@ def setup ...@@ -53,6 +51,102 @@ def setup
Dispatcher.raise_exception = nil Dispatcher.raise_exception = nil
end end
def test_process_restart
@handler.stubs(:when_ready).returns(:restart)
@handler.expects(:close_connection)
@handler.expects(:restart!)
@handler.process!
end
def test_process_exit
@handler.stubs(:when_ready).returns(:exit)
@handler.expects(:close_connection)
@handler.process!
end
def test_process_breakpoint
@handler.stubs(:when_ready).returns(:breakpoint)
@handler.expects(:close_connection)
@handler.expects(:breakpoint!)
@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")
@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_breakpoint_handler
@handler.expects(:dispatcher_log).with(:info, "asked to breakpoint ASAP")
@handler.send(:breakpoint_handler, nil)
assert_equal :breakpoint, @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")
@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!)
@handler.expects(:dispatcher_log).with(:info, "reloaded")
@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"
end
def test_restore!
$".expects(:replace)
Dispatcher.expects(:reset_application!)
ActionController::Routing::Routes.expects(:reload)
@handler.send(:restore!)
end
def test_breakpoint!
@handler.expects(:require).with('breakpoint')
Breakpoint.expects(:activate_drb)
@handler.expects(:breakpoint)
@handler.expects(:dispatcher_log).with(:info, "breakpointing")
@handler.send(:breakpoint!)
assert_nil @handler.when_ready
end
def test_uninterrupted_processing def test_uninterrupted_processing
@handler.process! @handler.process!
assert_nil @handler.exit_code assert_nil @handler.exit_code
...@@ -60,6 +154,7 @@ def test_uninterrupted_processing ...@@ -60,6 +154,7 @@ def test_uninterrupted_processing
end end
def test_interrupted_via_HUP_when_not_in_request def test_interrupted_via_HUP_when_not_in_request
@handler.expects(:reload!)
FCGI.time_to_sleep = 1 FCGI.time_to_sleep = 1
@handler.thread = Thread.new { @handler.process! } @handler.thread = Thread.new { @handler.process! }
sleep 0.1 # let the thread get started sleep 0.1 # let the thread get started
...@@ -67,10 +162,11 @@ def test_interrupted_via_HUP_when_not_in_request ...@@ -67,10 +162,11 @@ def test_interrupted_via_HUP_when_not_in_request
@handler.thread.join @handler.thread.join
assert_nil @handler.exit_code assert_nil @handler.exit_code
assert_equal :reload, @handler.when_ready assert_equal :reload, @handler.when_ready
assert @handler.reloaded
end end
def test_interrupted_via_HUP_when_in_request def test_interrupted_via_HUP_when_in_request
@handler.expects(:reload!)
Dispatcher.time_to_sleep = 1 Dispatcher.time_to_sleep = 1
@handler.thread = Thread.new { @handler.process! } @handler.thread = Thread.new { @handler.process! }
sleep 0.1 # let the thread get started sleep 0.1 # let the thread get started
...@@ -78,7 +174,6 @@ def test_interrupted_via_HUP_when_in_request ...@@ -78,7 +174,6 @@ def test_interrupted_via_HUP_when_in_request
@handler.thread.join @handler.thread.join
assert_nil @handler.exit_code assert_nil @handler.exit_code
assert_equal :reload, @handler.when_ready assert_equal :reload, @handler.when_ready
assert @handler.reloaded
end end
def test_interrupted_via_USR1_when_not_in_request def test_interrupted_via_USR1_when_not_in_request
......
module ActionController
module Routing
class Routes
end
end
end
module Kernel
def exec(*args)
true
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册