diff options
author | Jacob Vosmaer <jacob@gitlab.com> | 2017-04-20 14:51:38 +0200 |
---|---|---|
committer | Jacob Vosmaer <jacob@gitlab.com> | 2017-04-26 16:39:12 +0200 |
commit | b325d4a658bd884d2d10b832032296e9e28bcc24 (patch) | |
tree | 3cee11210c8f7a8e534df247e77049719ffbfe50 /spec/unicorn | |
parent | a9da37434af6d44c5f851affd4bd69b370760e8e (diff) | |
download | gitlab-ce-b325d4a658bd884d2d10b832032296e9e28bcc24.tar.gz |
Add test that asserts unicorns terminate
Diffstat (limited to 'spec/unicorn')
-rw-r--r-- | spec/unicorn/unicorn_spec.rb | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/spec/unicorn/unicorn_spec.rb b/spec/unicorn/unicorn_spec.rb new file mode 100644 index 00000000000..30fc5562353 --- /dev/null +++ b/spec/unicorn/unicorn_spec.rb @@ -0,0 +1,89 @@ +require 'fileutils' + +require 'excon' + +require 'spec_helper' + +describe 'Unicorn' do + before(:all) do + config_lines = File.read('config/unicorn.rb.example').split("\n") + + # Remove these because they make setup harder. + config_lines = config_lines.reject do |line| + %w[ + pid + stderr_path + stdout_path + ].any? { |prefix| line.start_with?(prefix) } + end + + config_lines = config_lines.reject { |l| l.start_with?('working_directory') } + config_lines << "working_directory '#{Rails.root}'" + + # We want to have exactly 1 worker process because that makes it + # predictable which process will handle our requests. + config_lines = config_lines.reject { |l| l.start_with?('worker_processes') } + config_lines << 'worker_processes 1' + + @socket_path = File.join(Dir.pwd, 'tmp/tests/unicorn.socket') + config_lines = config_lines.reject { |l| l.start_with?('listen') } + config_lines << "listen '#{@socket_path}'" + + ready_file = 'tmp/tests/unicorn-worker-ready' + FileUtils.rm_f(ready_file) + after_fork_index = config_lines.index { |l| l.start_with?('after_fork') } + config_lines.insert(after_fork_index + 1, "File.write('#{ready_file}', Process.pid)") + + config_path = 'tmp/tests/unicorn.rb' + File.write(config_path, config_lines.join("\n") + "\n") + + cmd = %W[unicorn -E test -c #{config_path} #{Rails.root.join('config.ru')}] + @unicorn_master_pid = spawn(*cmd) + + 120.times do + break if File.exist?(ready_file) + pid = Process.waitpid(@unicorn_master_pid, Process::WNOHANG) + raise "unicorn failed to boot: #{$?}" unless pid.nil? + + sleep 1 + end + 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:///unicorn_test/pid', socket: @socket_path) + expect(response.status).to eq(200) + + worker_pid = response.body.to_i + expect(worker_pid > 0).to eq(true) + + begin + Excon.post('unix:///unicorn_test/kill', socket: @socket_path, body: "signal=#{signal}") + rescue Excon::Error::Socket + # The connection may be closed abruptly + end + + expect(pid_gone?(worker_pid)).to eq(true) + end + end + + after(:all) do + WebMock.disable_net_connect!(allow_localhost: true) + Process.kill('TERM', @unicorn_master_pid) + end + + def pid_gone?(pid) + 10.times do + begin + Process.kill(0, pid) + rescue Errno::ESRCH + return true + end + + sleep 1 + end + + false + end +end |