2018-12-13 13:39:08 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'fileutils'
|
|
|
|
|
|
|
|
require 'excon'
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
describe 'Puma' do
|
|
|
|
before(:all) do
|
|
|
|
project_root = File.expand_path('../..', __dir__)
|
|
|
|
|
|
|
|
config_lines = File.read('spec/rack_servers/configs/puma.rb')
|
|
|
|
.gsub('/home/git/gitlab', project_root)
|
|
|
|
.gsub('/home/git', project_root)
|
|
|
|
|
|
|
|
config_path = File.join(project_root, "tmp/tests/puma.rb")
|
|
|
|
@socket_path = File.join(project_root, 'tmp/tests/puma.socket')
|
|
|
|
|
|
|
|
File.write(config_path, config_lines)
|
|
|
|
|
|
|
|
cmd = %W[puma -e test -C #{config_path} #{File.join(__dir__, 'configs/config.ru')}]
|
|
|
|
@puma_master_pid = spawn(*cmd)
|
|
|
|
wait_puma_boot!(@puma_master_pid, File.join(project_root, 'tmp/tests/puma-worker-ready'))
|
|
|
|
WebMock.allow_net_connect!
|
|
|
|
end
|
|
|
|
|
|
|
|
%w[SIGQUIT SIGTERM SIGKILL].each do |signal|
|
|
|
|
it "has a worker that self-terminates on signal #{signal}" do
|
|
|
|
response = Excon.get('unix://', socket: @socket_path)
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
|
|
|
|
worker_pid = response.body.to_i
|
|
|
|
expect(worker_pid).to be > 0
|
|
|
|
|
|
|
|
begin
|
|
|
|
Excon.post("unix://?#{signal}", socket: @socket_path)
|
|
|
|
rescue Excon::Error::Socket
|
|
|
|
# The connection may be closed abruptly
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(pid_gone?(worker_pid)).to eq(true)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
after(:all) do
|
2019-05-18 00:54:41 +05:30
|
|
|
WebMock.disable_net_connect!(allow_localhost: true)
|
|
|
|
Process.kill('TERM', @puma_master_pid)
|
|
|
|
rescue Errno::ESRCH
|
2018-12-13 13:39:08 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def wait_puma_boot!(master_pid, ready_file)
|
|
|
|
# We have seen the boot timeout after 2 minutes in CI so let's set it to 5 minutes.
|
|
|
|
timeout = 5 * 60
|
|
|
|
timeout.times do
|
|
|
|
return if File.exist?(ready_file)
|
|
|
|
|
|
|
|
pid = Process.waitpid(master_pid, Process::WNOHANG)
|
|
|
|
raise "puma failed to boot: #{$?}" unless pid.nil?
|
|
|
|
|
|
|
|
sleep 1
|
|
|
|
end
|
|
|
|
|
|
|
|
raise "puma boot timed out after #{timeout} seconds"
|
|
|
|
end
|
|
|
|
|
|
|
|
def pid_gone?(pid)
|
|
|
|
# Worker termination should take less than a second. That makes 10
|
|
|
|
# seconds a generous timeout.
|
|
|
|
10.times do
|
|
|
|
begin
|
|
|
|
Process.kill(0, pid)
|
|
|
|
rescue Errno::ESRCH
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
sleep 1
|
|
|
|
end
|
|
|
|
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|