PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/railties/test/fcgi_dispatcher_test.rb

https://bitbucket.org/nicksieger/rails
Ruby | 264 lines | 205 code | 58 blank | 1 comment | 0 complexity | 5965a24fb1dbafebe183bd9a21464c58 MD5 | raw file
  1. require 'abstract_unit'
  2. uses_gem "fcgi", "0.8.7" do
  3. require 'action_controller'
  4. require 'fcgi_handler'
  5. Dispatcher.middleware.clear
  6. class RailsFCGIHandlerTest < Test::Unit::TestCase
  7. def setup
  8. @log = StringIO.new
  9. @handler = RailsFCGIHandler.new(@log)
  10. end
  11. def test_process_restart
  12. request = mock
  13. FCGI.stubs(:each).yields(request)
  14. @handler.expects(:process_request).once
  15. @handler.expects(:dispatcher_error).never
  16. @handler.expects(:when_ready).returns(:restart)
  17. @handler.expects(:close_connection).with(request)
  18. @handler.expects(:reload!).never
  19. @handler.expects(:restart!)
  20. @handler.process!
  21. end
  22. def test_process_exit
  23. request = mock
  24. FCGI.stubs(:each).yields(request)
  25. @handler.expects(:process_request).once
  26. @handler.expects(:dispatcher_error).never
  27. @handler.expects(:when_ready).returns(:exit)
  28. @handler.expects(:close_connection).with(request)
  29. @handler.expects(:reload!).never
  30. @handler.expects(:restart!).never
  31. @handler.process!
  32. end
  33. def test_process_with_system_exit_exception
  34. request = mock
  35. FCGI.stubs(:each).yields(request)
  36. @handler.expects(:process_request).once.raises(SystemExit)
  37. @handler.stubs(:dispatcher_log)
  38. @handler.expects(:dispatcher_log).with(:info, regexp_matches(/^stopping/))
  39. @handler.expects(:dispatcher_error).never
  40. @handler.expects(:when_ready).never
  41. @handler.expects(:close_connection).never
  42. @handler.expects(:reload!).never
  43. @handler.expects(:restart!).never
  44. @handler.process!
  45. end
  46. def test_restart_handler_outside_request
  47. @handler.expects(:dispatcher_log).with(:info, "asked to restart ASAP")
  48. @handler.expects(:restart!).once
  49. @handler.send(:restart_handler, nil)
  50. assert_equal nil, @handler.when_ready
  51. end
  52. def test_install_signal_handler_should_log_on_bad_signal
  53. @handler.stubs(:trap).raises(ArgumentError)
  54. @handler.expects(:dispatcher_log).with(:warn, "Ignoring unsupported signal CHEESECAKE.")
  55. @handler.send(:install_signal_handler, "CHEESECAKE", nil)
  56. end
  57. def test_reload
  58. @handler.expects(:restore!)
  59. @handler.expects(:dispatcher_log).with(:info, "reloaded")
  60. @handler.send(:reload!)
  61. assert_nil @handler.when_ready
  62. end
  63. def test_reload_runs_gc_when_gc_request_period_set
  64. @handler.expects(:run_gc!)
  65. @handler.expects(:restore!)
  66. @handler.expects(:dispatcher_log).with(:info, "reloaded")
  67. @handler.gc_request_period = 10
  68. @handler.send(:reload!)
  69. end
  70. def test_reload_doesnt_run_gc_if_gc_request_period_isnt_set
  71. @handler.expects(:run_gc!).never
  72. @handler.expects(:restore!)
  73. @handler.expects(:dispatcher_log).with(:info, "reloaded")
  74. @handler.send(:reload!)
  75. end
  76. def test_restart!
  77. @handler.expects(:dispatcher_log).with(:info, "restarted")
  78. @handler.expects(:exec).returns('restarted')
  79. assert_equal 'restarted', @handler.send(:restart!)
  80. end
  81. def test_restore!
  82. $".expects(:replace)
  83. Dispatcher.expects(:reset_application!)
  84. ActionController::Routing::Routes.expects(:reload)
  85. @handler.send(:restore!)
  86. end
  87. def test_uninterrupted_processing
  88. request = mock
  89. FCGI.expects(:each).yields(request)
  90. @handler.expects(:process_request).with(request)
  91. @handler.process!
  92. assert_nil @handler.when_ready
  93. end
  94. end
  95. class RailsFCGIHandlerSignalsTest < Test::Unit::TestCase
  96. class ::RailsFCGIHandler
  97. attr_accessor :signal
  98. alias_method :old_gc_countdown, :gc_countdown
  99. def gc_countdown
  100. signal ? Process.kill(signal, $$) : old_gc_countdown
  101. end
  102. end
  103. def setup
  104. @log = StringIO.new
  105. @handler = RailsFCGIHandler.new(@log)
  106. @dispatcher = mock
  107. Dispatcher.stubs(:new).returns(@dispatcher)
  108. end
  109. def test_interrupted_via_HUP_when_not_in_request
  110. request = mock
  111. FCGI.expects(:each).once.yields(request)
  112. @handler.expects(:signal).times(2).returns('HUP')
  113. @handler.expects(:reload!).once
  114. @handler.expects(:close_connection).never
  115. @handler.expects(:exit).never
  116. @handler.process!
  117. assert_equal :reload, @handler.when_ready
  118. end
  119. def test_interrupted_via_USR1_when_not_in_request
  120. request = mock
  121. FCGI.expects(:each).once.yields(request)
  122. @handler.expects(:signal).times(2).returns('USR1')
  123. @handler.expects(:exit_handler).never
  124. @handler.expects(:reload!).never
  125. @handler.expects(:close_connection).with(request).once
  126. @handler.expects(:exit).never
  127. @handler.process!
  128. assert_nil @handler.when_ready
  129. end
  130. def test_restart_via_USR2_when_in_request
  131. request = mock
  132. FCGI.expects(:each).once.yields(request)
  133. @handler.expects(:signal).times(2).returns('USR2')
  134. @handler.expects(:exit_handler).never
  135. @handler.expects(:reload!).never
  136. @handler.expects(:close_connection).with(request).once
  137. @handler.expects(:exit).never
  138. @handler.expects(:restart!).once
  139. @handler.process!
  140. assert_equal :restart, @handler.when_ready
  141. end
  142. def test_interrupted_via_TERM
  143. request = mock
  144. FCGI.expects(:each).once.yields(request)
  145. ::Rack::Handler::FastCGI.expects(:serve).once.returns('TERM')
  146. @handler.expects(:reload!).never
  147. @handler.expects(:close_connection).never
  148. @handler.process!
  149. assert_nil @handler.when_ready
  150. end
  151. def test_runtime_exception_in_fcgi
  152. error = RuntimeError.new('foo')
  153. FCGI.expects(:each).times(2).raises(error)
  154. @handler.expects(:dispatcher_error).with(error, regexp_matches(/^retrying/))
  155. @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
  156. @handler.process!
  157. end
  158. def test_runtime_error_in_dispatcher
  159. request = mock
  160. error = RuntimeError.new('foo')
  161. FCGI.expects(:each).once.yields(request)
  162. ::Rack::Handler::FastCGI.expects(:serve).once.raises(error)
  163. @handler.expects(:dispatcher_error).with(error, regexp_matches(/^unhandled/))
  164. @handler.process!
  165. end
  166. def test_signal_exception_in_fcgi
  167. error = SignalException.new('USR2')
  168. FCGI.expects(:each).once.raises(error)
  169. @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
  170. @handler.process!
  171. end
  172. def test_signal_exception_in_dispatcher
  173. request = mock
  174. error = SignalException.new('USR2')
  175. FCGI.expects(:each).once.yields(request)
  176. ::Rack::Handler::FastCGI.expects(:serve).once.raises(error)
  177. @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
  178. @handler.process!
  179. end
  180. end
  181. class RailsFCGIHandlerPeriodicGCTest < Test::Unit::TestCase
  182. def setup
  183. @log = StringIO.new
  184. end
  185. def teardown
  186. GC.enable
  187. end
  188. def test_normal_gc
  189. @handler = RailsFCGIHandler.new(@log)
  190. assert_nil @handler.gc_request_period
  191. # When GC is enabled, GC.disable disables and returns false.
  192. assert_equal false, GC.disable
  193. end
  194. def test_periodic_gc
  195. @handler = RailsFCGIHandler.new(@log, 10)
  196. assert_equal 10, @handler.gc_request_period
  197. request = mock
  198. FCGI.expects(:each).times(10).yields(request)
  199. @handler.expects(:run_gc!).never
  200. 9.times { @handler.process! }
  201. @handler.expects(:run_gc!).once
  202. @handler.process!
  203. assert_nil @handler.when_ready
  204. end
  205. end
  206. end # uses_gem "fcgi"