mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
39d16fadaf
* Add pumactl command to print thread backtraces Completes 1 of 2 items from #1964 This commit adds an endpoint to the status app to print thread backtraces, and control cli command to call that endpoint. I tried this locally by starting a server with: ```sh bundle exec bin/puma test/rackup/hello.ru \ --control-url="unix://test.sock" \ --control-token="token" ``` and then printing the backtraces with: ```sh bundle exec bin/pumactl thread-backtraces \ --control-url="unix://test.sock" \ --control-token="token" ``` * Log threads as JSON in control app With this commit the status app sends the thread backtraces as an array of objects with `name` and `backtrace` keys, rather than as a string matching the SIGINFO output. While working on this I noticed that we logged the thread TID twice. This commit simplifies that so we only log the thread TID once, with both the label (I don't know when the label would get set) and name if they are available.
104 lines
3 KiB
Ruby
104 lines
3 KiB
Ruby
require_relative "helper"
|
|
require_relative "helpers/integration"
|
|
|
|
class TestIntegrationSingle < TestIntegration
|
|
parallelize_me!
|
|
|
|
def test_usr2_restart
|
|
skip_unless_signal_exist? :USR2
|
|
_, new_reply = restart_server_and_listen("-q test/rackup/hello.ru")
|
|
assert_equal "Hello World", new_reply
|
|
end
|
|
|
|
# It does not share environments between multiple generations, which would break Dotenv
|
|
def test_usr2_restart_restores_environment
|
|
# jruby has a bug where setting `nil` into the ENV or `delete` do not change the
|
|
# next workers ENV
|
|
skip_on :jruby
|
|
skip_unless_signal_exist? :USR2
|
|
|
|
initial_reply, new_reply = restart_server_and_listen("-q test/rackup/hello-env.ru")
|
|
|
|
assert_includes initial_reply, "Hello RAND"
|
|
assert_includes new_reply, "Hello RAND"
|
|
refute_equal initial_reply, new_reply
|
|
end
|
|
|
|
def test_term_exit_code
|
|
skip_unless_signal_exist? :TERM
|
|
skip_on :jruby # JVM does not return correct exit code for TERM
|
|
|
|
cli_server "test/rackup/hello.ru"
|
|
_, status = stop_server
|
|
|
|
assert_equal 15, status
|
|
end
|
|
|
|
def test_term_suppress
|
|
skip_unless_signal_exist? :TERM
|
|
|
|
cli_server "-C test/config/suppress_exception.rb test/rackup/hello.ru"
|
|
_, status = stop_server
|
|
|
|
assert_equal 0, status
|
|
end
|
|
|
|
def test_term_not_accepts_new_connections
|
|
skip_unless_signal_exist? :TERM
|
|
skip_on :jruby
|
|
|
|
cli_server 'test/rackup/sleep.ru'
|
|
|
|
_stdin, curl_stdout, _stderr, curl_wait_thread = Open3.popen3("curl http://#{HOST}:#{@tcp_port}/sleep10")
|
|
sleep 1 # ensure curl send a request
|
|
|
|
Process.kill :TERM, @pid
|
|
true while @server.gets !~ /Gracefully stopping/ # wait for server to begin graceful shutdown
|
|
|
|
# Invoke a request which must be rejected
|
|
_stdin, _stdout, rejected_curl_stderr, rejected_curl_wait_thread = Open3.popen3("curl #{HOST}:#{@tcp_port}")
|
|
|
|
assert nil != Process.getpgid(@server.pid) # ensure server is still running
|
|
assert nil != Process.getpgid(rejected_curl_wait_thread[:pid]) # ensure first curl invokation still in progress
|
|
|
|
curl_wait_thread.join
|
|
rejected_curl_wait_thread.join
|
|
|
|
assert_match(/Slept 10/, curl_stdout.read)
|
|
assert_match(/Connection refused/, rejected_curl_stderr.read)
|
|
|
|
Process.wait(@server.pid)
|
|
@server.close unless @server.closed?
|
|
@server = nil # prevent `#teardown` from killing already killed server
|
|
end
|
|
|
|
def test_int_refuse
|
|
skip_unless_signal_exist? :INT
|
|
|
|
cli_server 'test/rackup/hello.ru'
|
|
begin
|
|
sock = TCPSocket.new(HOST, @tcp_port)
|
|
sock.close
|
|
rescue => ex
|
|
fail("Port didn't open properly: #{ex.message}")
|
|
end
|
|
|
|
Process.kill :INT, @pid
|
|
Process.wait @pid
|
|
|
|
assert_raises(Errno::ECONNREFUSED) { TCPSocket.new(HOST, @tcp_port) }
|
|
end
|
|
|
|
def test_siginfo_thread_print
|
|
skip_unless_signal_exist? :INFO
|
|
|
|
cli_server 'test/rackup/hello.ru'
|
|
output = []
|
|
t = Thread.new { output << @server.readlines }
|
|
Process.kill :INFO, @pid
|
|
Process.kill :INT , @pid
|
|
t.join
|
|
|
|
assert_match "Thread: TID", output.join
|
|
end
|
|
end
|