aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Tagua <miloops@gmail.com>2009-10-05 15:33:59 -0300
committerEmilio Tagua <miloops@gmail.com>2009-10-05 15:33:59 -0300
commit97aba353c80d3a55f79f9d280035be566c3bc0ef (patch)
tree7915c7a2986f48f166ded4277e637bedf4ef1a4f
parent23c168a4fdd5a8f2191283d1d5c626c348fb6ae0 (diff)
parent570f055c44a0b6da973f63689f8fedbef9fe32d3 (diff)
downloadrails-97aba353c80d3a55f79f9d280035be566c3bc0ef.tar.gz
rails-97aba353c80d3a55f79f9d280035be566c3bc0ef.tar.bz2
rails-97aba353c80d3a55f79f9d280035be566c3bc0ef.zip
Merge commit 'rails/master'
-rw-r--r--actionpack/lib/action_controller/dispatch/dispatcher.rb2
-rwxr-xr-xrailties/lib/rails/commands/ncgi/listener86
-rw-r--r--railties/lib/rails/fcgi_handler.rb239
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb16
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.fcgi24
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.rb10
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/dispatchers/gateway.cgi97
-rw-r--r--railties/lib/rails/tasks/framework.rake5
-rw-r--r--railties/test/abstract_unit.rb8
-rw-r--r--railties/test/application/console_test.rb52
-rw-r--r--railties/test/application/load_test.rb7
-rw-r--r--railties/test/console_app_test.rb43
-rw-r--r--railties/test/fcgi_dispatcher_test.rb268
-rw-r--r--railties/test/generators/app_generator_test.rb12
-rw-r--r--railties/test/isolation/abstract_unit.rb4
15 files changed, 64 insertions, 809 deletions
diff --git a/actionpack/lib/action_controller/dispatch/dispatcher.rb b/actionpack/lib/action_controller/dispatch/dispatcher.rb
index e04da42637..008fb54715 100644
--- a/actionpack/lib/action_controller/dispatch/dispatcher.rb
+++ b/actionpack/lib/action_controller/dispatch/dispatcher.rb
@@ -50,7 +50,7 @@ module ActionController
def new
# DEPRECATE Rails application fallback
- Rails.application
+ Rails.application.new
end
end
end
diff --git a/railties/lib/rails/commands/ncgi/listener b/railties/lib/rails/commands/ncgi/listener
deleted file mode 100755
index 7079ef78a6..0000000000
--- a/railties/lib/rails/commands/ncgi/listener
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'stringio'
-require 'fileutils'
-require 'fcgi_handler'
-
-def message(s)
- $stderr.puts "listener: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
-end
-
-class RemoteCGI < CGI
- attr_accessor :stdinput, :stdoutput, :env_table
- def initialize(env_table, input = nil, output = nil)
- self.env_table = env_table
- self.stdinput = input || StringIO.new
- self.stdoutput = output || StringIO.new
- super()
- end
-
- def out(stream) # Ignore the requested output stream
- super(stdoutput)
- end
-end
-
-class Listener
- include DRbUndumped
-
- def initialize(timeout, socket_path)
- @socket = File.expand_path(socket_path)
- @mutex = Mutex.new
- @active = false
- @timeout = timeout
-
- @handler = RailsFCGIHandler.new
- @handler.extend DRbUndumped
-
- message 'opening socket'
- DRb.start_service("drbunix:#{@socket}", self)
-
- message 'entering process loop'
- @handler.process! self
- end
-
- def each_cgi(&cgi_block)
- @cgi_block = cgi_block
- message 'entering idle loop'
- loop do
- sleep @timeout rescue nil
- die! unless @active
- @active = false
- end
- end
-
- def process(env, input)
- message 'received request'
- @mutex.synchronize do
- @active = true
-
- message 'creating input stream'
- input_stream = StringIO.new(input)
- message 'building CGI instance'
- cgi = RemoteCGI.new(eval(env), input_stream)
-
- message 'yielding to fcgi handler'
- @cgi_block.call cgi
- message 'yield finished -- sending output'
-
- cgi.stdoutput.seek(0)
- output = cgi.stdoutput.read
-
- return output
- end
- end
-
- def die!
- message 'shutting down'
- DRb.stop_service
- FileUtils.rm_f @socket
- Kernel.exit 0
- end
-end
-
-socket_path = ARGV.shift
-timeout = (ARGV.shift || 90).to_i
-
-Listener.new(timeout, socket_path)
diff --git a/railties/lib/rails/fcgi_handler.rb b/railties/lib/rails/fcgi_handler.rb
deleted file mode 100644
index ef6f3b094c..0000000000
--- a/railties/lib/rails/fcgi_handler.rb
+++ /dev/null
@@ -1,239 +0,0 @@
-require 'fcgi'
-require 'logger'
-require 'rails/dispatcher'
-require 'rbconfig'
-
-class RailsFCGIHandler
- SIGNALS = {
- 'HUP' => :reload,
- 'INT' => :exit_now,
- 'TERM' => :exit_now,
- 'USR1' => :exit,
- 'USR2' => :restart
- }
- GLOBAL_SIGNALS = SIGNALS.keys - %w(USR1)
-
- attr_reader :when_ready
-
- attr_accessor :log_file_path
- attr_accessor :gc_request_period
-
- # Initialize and run the FastCGI instance, passing arguments through to new.
- def self.process!(*args, &block)
- new(*args, &block).process!
- end
-
- # Initialize the FastCGI instance with the path to a crash log
- # detailing unhandled exceptions (default RAILS_ROOT/log/fastcgi.crash.log)
- # and the number of requests to process between garbage collection runs
- # (default nil for normal GC behavior.) Optionally, pass a block which
- # takes this instance as an argument for further configuration.
- def initialize(log_file_path = nil, gc_request_period = nil)
- self.log_file_path = log_file_path || "#{RAILS_ROOT}/log/fastcgi.crash.log"
- self.gc_request_period = gc_request_period
-
- # Yield for additional configuration.
- yield self if block_given?
-
- # Safely install signal handlers.
- install_signal_handlers
-
- @app = Dispatcher.new
-
- # Start error timestamp at 11 seconds ago.
- @last_error_on = Time.now - 11
- end
-
- def process!(provider = FCGI)
- mark_features!
-
- dispatcher_log :info, 'starting'
- process_each_request provider
- dispatcher_log :info, 'stopping gracefully'
-
- rescue Exception => error
- case error
- when SystemExit
- dispatcher_log :info, 'stopping after explicit exit'
- when SignalException
- dispatcher_error error, 'stopping after unhandled signal'
- else
- # Retry if exceptions occur more than 10 seconds apart.
- if Time.now - @last_error_on > 10
- @last_error_on = Time.now
- dispatcher_error error, 'retrying after unhandled exception'
- retry
- else
- dispatcher_error error, 'stopping after unhandled exception within 10 seconds of the last'
- end
- end
- end
-
- protected
- def process_each_request(provider)
- request = nil
-
- catch :exit do
- provider.each do |request|
- process_request(request)
-
- case when_ready
- when :reload
- reload!
- when :restart
- close_connection(request)
- restart!
- when :exit
- close_connection(request)
- throw :exit
- end
- end
- end
- rescue SignalException => signal
- raise unless signal.message == 'SIGUSR1'
- close_connection(request)
- end
-
- def process_request(request)
- @processing, @when_ready = true, nil
- gc_countdown
-
- with_signal_handler 'USR1' do
- begin
- ::Rack::Handler::FastCGI.serve(request, @app)
- rescue SignalException, SystemExit
- raise
- rescue Exception => error
- dispatcher_error error, 'unhandled dispatch error'
- end
- end
- ensure
- @processing = false
- end
-
- def logger
- @logger ||= Logger.new(@log_file_path)
- end
-
- def dispatcher_log(level, msg)
- time_str = Time.now.strftime("%d/%b/%Y:%H:%M:%S")
- logger.send(level, "[#{time_str} :: #{$$}] #{msg}")
- rescue Exception => log_error # Logger errors
- STDERR << "Couldn't write to #{@log_file_path.inspect}: #{msg}\n"
- STDERR << " #{log_error.class}: #{log_error.message}\n"
- end
-
- def dispatcher_error(e, msg = "")
- error_message =
- "Dispatcher failed to catch: #{e} (#{e.class})\n" +
- " #{e.backtrace.join("\n ")}\n#{msg}"
- dispatcher_log(:error, error_message)
- end
-
- def install_signal_handlers
- GLOBAL_SIGNALS.each { |signal| install_signal_handler(signal) }
- end
-
- def install_signal_handler(signal, handler = nil)
- if SIGNALS.include?(signal) && self.class.method_defined?(name = "#{SIGNALS[signal]}_handler")
- handler ||= method(name).to_proc
-
- begin
- trap(signal, handler)
- rescue ArgumentError
- dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
- end
- else
- dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
- end
- end
-
- def with_signal_handler(signal)
- install_signal_handler(signal)
- yield
- ensure
- install_signal_handler(signal, 'DEFAULT')
- end
-
- def exit_now_handler(signal)
- dispatcher_log :info, "asked to stop immediately"
- exit
- end
-
- def exit_handler(signal)
- dispatcher_log :info, "asked to stop ASAP"
- if @processing
- @when_ready = :exit
- else
- throw :exit
- end
- end
-
- def reload_handler(signal)
- dispatcher_log :info, "asked to reload ASAP"
- if @processing
- @when_ready = :reload
- else
- reload!
- end
- end
-
- def restart_handler(signal)
- dispatcher_log :info, "asked to restart ASAP"
- if @processing
- @when_ready = :restart
- else
- restart!
- end
- end
-
- def restart!
- config = ::Config::CONFIG
- ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
- command_line = [ruby, $0, ARGV].flatten.join(' ')
-
- dispatcher_log :info, "restarted"
-
- # close resources as they won't be closed by
- # the OS when using exec
- logger.close rescue nil
- Rails.logger.close rescue nil
-
- exec(command_line)
- end
-
- def reload!
- run_gc! if gc_request_period
- restore!
- @when_ready = nil
- dispatcher_log :info, "reloaded"
- end
-
- # Make a note of $" so we can safely reload this instance.
- def mark_features!
- @features = $".clone
- end
-
- def restore!
- $".replace @features
- Dispatcher.reset_application!
- ActionController::Routing::Routes.reload
- end
-
- def run_gc!
- @gc_request_countdown = gc_request_period
- GC.enable; GC.start; GC.disable
- end
-
- def gc_countdown
- if gc_request_period
- @gc_request_countdown ||= gc_request_period
- @gc_request_countdown -= 1
- run_gc! if @gc_request_countdown <= 0
- end
- end
-
- def close_connection(request)
- request.finish if request
- end
-end
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index b2322f90b4..78b4b057ae 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -18,9 +18,6 @@ module Rails::Generators
class_option :template, :type => :string, :aliases => "-m",
:desc => "Path to an application template (can be a filesystem path or URL)."
- class_option :with_dispatchers, :type => :boolean, :aliases => "-D", :default => false,
- :desc => "Add CGI/FastCGI/mod_ruby dispatchers code"
-
class_option :skip_activerecord, :type => :boolean, :aliases => "-O", :default => false,
:desc => "Skip ActiveRecord files"
@@ -113,19 +110,6 @@ module Rails::Generators
directory "public", "public", :recursive => false # Do small steps, so anyone can overwrite it.
end
- def create_dispatch_files
- return unless options[:with_dispatchers]
-
- template "dispatchers/dispatch.rb", "public/dispatch.rb"
- chmod "public/dispatch.rb", 0755, :verbose => false
-
- template "dispatchers/dispatch.rb", "public/dispatch.cgi"
- chmod "public/dispatch.cgi", 0755, :verbose => false
-
- template "dispatchers/dispatch.fcgi", "public/dispatch.fcgi"
- chmod "public/dispatch.fcgi", 0755, :verbose => false
- end
-
def create_public_image_files
directory "public/images"
end
diff --git a/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.fcgi b/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.fcgi
deleted file mode 100755
index f5b3b71875..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.fcgi
+++ /dev/null
@@ -1,24 +0,0 @@
-<%= shebang %>
-#
-# You may specify the path to the FastCGI crash log (a log of unhandled
-# exceptions which forced the FastCGI instance to exit, great for debugging)
-# and the number of requests to process before running garbage collection.
-#
-# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
-# and the GC period is nil (turned off). A reasonable number of requests
-# could range from 10-100 depending on the memory footprint of your app.
-#
-# Example:
-# # Default log path, normal GC behavior.
-# RailsFCGIHandler.process!
-#
-# # Default log path, 50 requests between GC.
-# RailsFCGIHandler.process! nil, 50
-#
-# # Custom log path, normal GC behavior.
-# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
-#
-require File.dirname(__FILE__) + "/../config/environment"
-require 'fcgi_handler'
-
-RailsFCGIHandler.process!
diff --git a/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.rb b/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.rb
deleted file mode 100755
index 48e888113a..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-<%= shebang %>
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch
diff --git a/railties/lib/rails/generators/rails/app/templates/dispatchers/gateway.cgi b/railties/lib/rails/generators/rails/app/templates/dispatchers/gateway.cgi
deleted file mode 100755
index bdc1055a22..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/dispatchers/gateway.cgi
+++ /dev/null
@@ -1,97 +0,0 @@
-<%= shebang %>
-
-require 'drb'
-
-# This file includes an experimental gateway CGI implementation. It will work
-# only on platforms which support both fork and sockets.
-#
-# To enable it edit public/.htaccess and replace dispatch.cgi with gateway.cgi.
-#
-# Next, create the directory log/drb_gateway and grant the apache user rw access
-# to said directory.
-#
-# On the next request to your server, the gateway tracker should start up, along
-# with a few listener processes. This setup should provide you with much better
-# speeds than dispatch.cgi.
-#
-# Keep in mind that the first request made to the server will be slow, as the
-# tracker and listeners will have to load. Also, the tracker and listeners will
-# shutdown after a period if inactivity. You can set this value below -- the
-# default is 90 seconds.
-
-TrackerSocket = File.expand_path(File.join(File.dirname(__FILE__), '../log/drb_gateway/tracker.sock'))
-DieAfter = 90 # Seconds
-Listeners = 3
-
-def message(s)
- $stderr.puts "gateway.cgi: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
-end
-
-def listener_socket(number)
- File.expand_path(File.join(File.dirname(__FILE__), "../log/drb_gateway/listener_#{number}.sock"))
-end
-
-unless File.exist? TrackerSocket
- message "Starting tracker and #{Listeners} listeners"
- fork do
- Process.setsid
- STDIN.reopen "/dev/null"
- STDOUT.reopen "/dev/null", "a"
-
- root = File.expand_path(File.dirname(__FILE__) + '/..')
-
- message "starting tracker"
- fork do
- ARGV.clear
- ARGV << TrackerSocket << Listeners.to_s << DieAfter.to_s
- load File.join(root, 'script', 'tracker')
- end
-
- message "starting listeners"
- require File.join(root, 'config/environment.rb')
- Listeners.times do |number|
- fork do
- ARGV.clear
- ARGV << listener_socket(number) << DieAfter.to_s
- load File.join(root, 'script', 'listener')
- end
- end
- end
-
- message "waiting for tracker and listener to arise..."
- ready = false
- 10.times do
- sleep 0.5
- break if (ready = File.exist?(TrackerSocket) && File.exist?(listener_socket(0)))
- end
-
- if ready
- message "tracker and listener are ready"
- else
- message "Waited 5 seconds, listener and tracker not ready... dropping request"
- Kernel.exit 1
- end
-end
-
-DRb.start_service
-
-message "connecting to tracker"
-tracker = DRbObject.new_with_uri("drbunix:#{TrackerSocket}")
-
-input = $stdin.read
-$stdin.close
-
-env = ENV.inspect
-
-output = nil
-tracker.with_listener do |number|
- message "connecting to listener #{number}"
- socket = listener_socket(number)
- listener = DRbObject.new_with_uri("drbunix:#{socket}")
- output = listener.process(env, input)
- message "listener #{number} has finished, writing output"
-end
-
-$stdout.write output
-$stdout.flush
-$stdout.close
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index 17e16f26fd..16dd0af44e 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -110,11 +110,6 @@ namespace :rails do
invoke_from_app_generator :create_prototype_files
end
- desc "Generate dispatcher files in RAILS_ROOT/public"
- task :generate_dispatchers do
- invoke_from_app_generator :create_dispatch_files
- end
-
desc "Add new scripts to the application script/ directory"
task :scripts do
invoke_from_app_generator :create_script_files
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index 4510e6241c..6c6af0b2bf 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -25,11 +25,3 @@ if defined?(RAILS_ROOT)
else
RAILS_ROOT = File.dirname(__FILE__)
end
-
-def uses_gem(gem_name, test_name, version = '> 0')
- gem gem_name.to_s, version
- require gem_name.to_s
- yield
-rescue LoadError
- $stderr.puts "Skipping #{test_name} tests. `gem install #{gem_name}` and try again."
-end
diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb
new file mode 100644
index 0000000000..e8a4a4e158
--- /dev/null
+++ b/railties/test/application/console_test.rb
@@ -0,0 +1,52 @@
+require 'isolation/abstract_unit'
+
+class ConsoleTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ boot_rails
+
+ # Load steps taken from rails/commands/console.rb
+ require "#{rails_root}/config/environment"
+ require 'rails/console_app'
+ require 'rails/console_with_helpers'
+ end
+
+ def test_app_method_should_return_integration_session
+ console_session = app
+ assert_not_nil console_session
+ assert_instance_of ActionController::Integration::Session, console_session
+ end
+
+ def test_new_session_should_return_integration_session
+ session = new_session
+ assert_not_nil session
+ assert_instance_of ActionController::Integration::Session, session
+ end
+
+ def test_reload_should_fire_preparation_callbacks
+ a = b = c = nil
+
+ # TODO: These should be defined on the initializer
+ ActionDispatch::Callbacks.to_prepare { a = b = c = 1 }
+ ActionDispatch::Callbacks.to_prepare { b = c = 2 }
+ ActionDispatch::Callbacks.to_prepare { c = 3 }
+
+ # Hide Reloading... output
+ silence_stream(STDOUT) do
+ reload!
+ end
+
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+ end
+
+ def test_access_to_helpers
+ assert_not_nil helper
+ assert_instance_of ActionView::Base, helper
+ assert_equal 'Once upon a time in a world...',
+ helper.truncate('Once upon a time in a world far far away')
+ end
+end
diff --git a/railties/test/application/load_test.rb b/railties/test/application/load_test.rb
index 5158abdbb4..305cd7f273 100644
--- a/railties/test/application/load_test.rb
+++ b/railties/test/application/load_test.rb
@@ -43,6 +43,13 @@ module ApplicationTests
assert Rails.application.new.is_a?(Rails::Application)
end
+ # Passenger still uses AC::Dispatcher, so we need to
+ # keep it working for now
+ test "deprecated ActionController::Dispatcher still works" do
+ rackup
+ assert ActionController::Dispatcher.new.is_a?(Rails::Application)
+ end
+
test "the config object is available on the application object" do
rackup
assert_equal 'UTC', Rails.application.config.time_zone
diff --git a/railties/test/console_app_test.rb b/railties/test/console_app_test.rb
deleted file mode 100644
index 1437e6d885..0000000000
--- a/railties/test/console_app_test.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-require 'abstract_unit'
-
-require 'action_controller' # console_app uses 'action_controller/integration'
-
-require 'rails/dispatcher'
-require 'rails/console_app'
-
-module Rails
- def self.application
- ActionController::Routing::Routes
- end
-end
-
-# console_app sets Test::Unit.run to work around the at_exit hook in test/unit, which kills IRB
-if Test::Unit.respond_to?(:run=)
- Test::Unit.run = false
-
- class ConsoleAppTest < Test::Unit::TestCase
- def test_app_method_should_return_integration_session
- assert_nothing_thrown do
- console_session = app
- assert_not_nil console_session
- assert_instance_of ActionController::Integration::Session,
- console_session
- end
- end
-
- def test_reload_should_fire_preparation_callbacks
- a = b = c = nil
-
- ActionDispatch::Callbacks.to_prepare { a = b = c = 1 }
- ActionDispatch::Callbacks.to_prepare { b = c = 2 }
- ActionDispatch::Callbacks.to_prepare { c = 3 }
- ActionController::Routing::Routes.expects(:reload)
-
- reload!
-
- assert_equal 1, a
- assert_equal 2, b
- assert_equal 3, c
- end
- end
-end
diff --git a/railties/test/fcgi_dispatcher_test.rb b/railties/test/fcgi_dispatcher_test.rb
deleted file mode 100644
index 4d77a321a0..0000000000
--- a/railties/test/fcgi_dispatcher_test.rb
+++ /dev/null
@@ -1,268 +0,0 @@
-require 'abstract_unit'
-
-uses_gem "fcgi", "0.8.7" do
-
-require 'action_controller'
-require 'rails/fcgi_handler'
-
-module Rails
- def self.application
- ActionController::Routing::Routes
- end
-end
-
-class RailsFCGIHandlerTest < Test::Unit::TestCase
- def setup
- @log = StringIO.new
- @handler = RailsFCGIHandler.new(@log)
- end
-
- def test_process_restart
- request = mock
- FCGI.stubs(:each).yields(request)
-
- @handler.expects(:process_request).once
- @handler.expects(:dispatcher_error).never
-
- @handler.expects(:when_ready).returns(:restart)
- @handler.expects(:close_connection).with(request)
- @handler.expects(:reload!).never
- @handler.expects(:restart!)
-
- @handler.process!
- end
-
- def test_process_exit
- request = mock
- FCGI.stubs(:each).yields(request)
-
- @handler.expects(:process_request).once
- @handler.expects(:dispatcher_error).never
-
- @handler.expects(:when_ready).returns(:exit)
- @handler.expects(:close_connection).with(request)
- @handler.expects(:reload!).never
- @handler.expects(:restart!).never
-
- @handler.process!
- end
-
- def test_process_with_system_exit_exception
- request = mock
- FCGI.stubs(:each).yields(request)
-
- @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_outside_request
- @handler.expects(:dispatcher_log).with(:info, "asked to restart ASAP")
- @handler.expects(:restart!).once
-
- @handler.send(:restart_handler, nil)
- assert_equal nil, @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")
- @handler.expects(:exec).returns('restarted')
- assert_equal 'restarted', @handler.send(:restart!)
- end
-
- def test_restore!
- $".expects(:replace)
- Dispatcher.expects(:reset_application!)
- ActionController::Routing::Routes.expects(:reload)
- @handler.send(:restore!)
- end
-
- def test_uninterrupted_processing
- request = mock
- FCGI.expects(:each).yields(request)
- @handler.expects(:process_request).with(request)
-
- @handler.process!
-
- assert_nil @handler.when_ready
- end
-end
-
-
-class RailsFCGIHandlerSignalsTest < Test::Unit::TestCase
- class ::RailsFCGIHandler
- attr_accessor :signal
- alias_method :old_gc_countdown, :gc_countdown
- def gc_countdown
- signal ? Process.kill(signal, $$) : old_gc_countdown
- end
- end
-
- def setup
- @log = StringIO.new
- @handler = RailsFCGIHandler.new(@log)
- @dispatcher = mock
- Dispatcher.stubs(:new).returns(@dispatcher)
- end
-
- def test_interrupted_via_HUP_when_not_in_request
- request = mock
- FCGI.expects(:each).once.yields(request)
- @handler.expects(:signal).times(2).returns('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
- request = mock
- FCGI.expects(:each).once.yields(request)
- @handler.expects(:signal).times(2).returns('USR1')
- @handler.expects(:exit_handler).never
-
- @handler.expects(:reload!).never
- @handler.expects(:close_connection).with(request).once
- @handler.expects(:exit).never
-
- @handler.process!
- assert_nil @handler.when_ready
- end
-
- def test_restart_via_USR2_when_in_request
- request = mock
- FCGI.expects(:each).once.yields(request)
- @handler.expects(:signal).times(2).returns('USR2')
- @handler.expects(:exit_handler).never
-
- @handler.expects(:reload!).never
- @handler.expects(:close_connection).with(request).once
- @handler.expects(:exit).never
- @handler.expects(:restart!).once
-
- @handler.process!
- assert_equal :restart, @handler.when_ready
- end
-
- def test_interrupted_via_TERM
- request = mock
- FCGI.expects(:each).once.yields(request)
- ::Rack::Handler::FastCGI.expects(:serve).once.returns('TERM')
-
- @handler.expects(:reload!).never
- @handler.expects(:close_connection).never
-
- @handler.process!
- assert_nil @handler.when_ready
- end
-
- def test_runtime_exception_in_fcgi
- error = RuntimeError.new('foo')
- FCGI.expects(:each).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
- request = mock
- error = RuntimeError.new('foo')
- FCGI.expects(:each).once.yields(request)
- ::Rack::Handler::FastCGI.expects(:serve).once.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).once.raises(error)
- @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
- @handler.process!
- end
-
- def test_signal_exception_in_dispatcher
- request = mock
- error = SignalException.new('USR2')
- FCGI.expects(:each).once.yields(request)
- ::Rack::Handler::FastCGI.expects(:serve).once.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
- end
-
- def teardown
- GC.enable
- end
-
- def test_normal_gc
- @handler = RailsFCGIHandler.new(@log)
- assert_nil @handler.gc_request_period
-
- # When GC is enabled, GC.disable disables and returns false.
- assert_equal false, GC.disable
- end
-
- def test_periodic_gc
- @handler = RailsFCGIHandler.new(@log, 10)
- assert_equal 10, @handler.gc_request_period
-
- request = mock
- FCGI.expects(:each).times(10).yields(request)
-
- @handler.expects(:run_gc!).never
- 9.times { @handler.process! }
- @handler.expects(:run_gc!).once
- @handler.process!
-
- assert_nil @handler.when_ready
- end
-end
-end # uses_gem "fcgi"
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index afc0585fba..6e46c4ddc0 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -53,18 +53,6 @@ class AppGeneratorTest < GeneratorsTestCase
assert_match /Invalid value for \-\-database option/, content
end
- def test_dispatchers_are_not_added_by_default
- run_generator
- assert_no_file "public/dispatch.cgi"
- assert_no_file "public/dispatch.fcgi"
- end
-
- def test_dispatchers_are_added_if_required
- run_generator ["--with-dispatchers"]
- assert_file "public/dispatch.cgi"
- assert_file "public/dispatch.fcgi"
- end
-
def test_config_database_is_added_by_default
run_generator
assert_file "config/database.yml", /sqlite3/
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 869e8429cf..a55ee6c01d 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -30,6 +30,10 @@ module TestHelpers
def app_path(*args)
tmp_path(*%w[app] + args)
end
+
+ def rails_root
+ app_path
+ end
end
module Rack