diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-10-19 22:14:59 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-10-19 22:14:59 +0000 |
commit | d973de0d6dfdf799e111d9f9a71170b61a0ac100 (patch) | |
tree | 35fbb97fa5697eb398e243d0325523f24d903358 /test/test_bin.rb | |
parent | 9cd4a50c275bbda9ee23f0351f1eba2289af075f (diff) | |
download | yahns-d973de0d6dfdf799e111d9f9a71170b61a0ac100.tar.gz |
We no longer have to worry about 1.8 compatibility, so use Process.spawn and shorten our code. Also, add tests for this functionality.
Diffstat (limited to 'test/test_bin.rb')
-rw-r--r-- | test/test_bin.rb | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/test/test_bin.rb b/test/test_bin.rb index aab4616..d21e8b9 100644 --- a/test/test_bin.rb +++ b/test/test_bin.rb @@ -94,4 +94,83 @@ class TestBin < Testcase end @pid.close! if @pid end + + def test_usr2_preload_noworker; usr2(true, false); end + def test_usr2_preload_worker; usr2(true, true); end + def test_usr2_nopreload_worker; usr2(false, true); end + def test_usr2_nopreload_noworker; usr2(false, false); end + + def usr2(preload, worker) + Dir.mktmpdir { |tmpdir| usr2_dir(tmpdir, preload, worker) } + end + + def usr2_dir(tmpdir, preload, worker) + exe = "#{tmpdir}/yahns" + + # need to fork here since tests are MT and the FD can leak out and go to + # other processes which fork (but do not exec), causing ETXTBUSY on + # Process.spawn + pid = fork do + ruby = "#!#{`which ruby`}" + File.open(exe, "w") { |y| + lines = File.readlines("bin/yahns") + lines[0] = ruby + y.chmod(0755) + y.syswrite(lines.join) + } + end + _, status = Process.waitpid2(pid) + assert status.success?, status.inspect + + @pid = tmpfile(%w(test_bin_daemon .pid)) + host, port = @srv.addr[3], @srv.addr[1] + @ru = tmpfile(%w(test_bin_daemon .ru)) + @ru.puts("use Rack::ContentLength") + @ru.puts("use Rack::ContentType, 'text/plain'") + @ru.puts("run lambda { |_| [ 200, {}, [ Process.pid.to_s ] ] }") + cfg = tmpfile(%w(test_bin_daemon_conf .rb)) + cfg.puts "pid '#{@pid.path}'" + cfg.puts "stderr_path '#{@err.path}'" + cfg.puts "worker_processes 1" if worker + cfg.puts "app(:rack, '#{@ru.path}', preload: #{preload}) do" + cfg.puts " listen '#{host}:#{port}'" + cfg.puts "end" + env = { + "YAHNS_FD" => @srv.fileno.to_s, + "PATH" => "#{tmpdir}:#{ENV['PATH']}", + "RUBYLIB" => "#{Dir.pwd}/lib", + } + cmd = %W(#{exe} -D -c #{cfg.path}) + cmd << { @srv => @srv, close_others: true } + pid = GTL.synchronize { Process.spawn(env, *cmd) } + res = Net::HTTP.start(host, port) { |h| h.get("/") } + assert_equal 200, res.code.to_i + orig = res.body + Process.kill(:USR2, pid) + Timeout.timeout(10) do + begin + sleep 0.01 + newpid = File.read(@pid.path) + rescue Errno::ENOENT + end until newpid.to_i != pid + end + Process.kill(:QUIT, pid) + _, status = Timeout.timeout(10) { Process.waitpid2(pid) } + assert status.success?, status + res = Net::HTTP.start(host, port) { |h| h.get("/") } + assert_equal 200, res.code.to_i + refute_equal orig, res.body + rescue => e + Yahns::Log.exception(Logger.new($stderr), "test", e) + raise + ensure + File.unlink(exe) if exe + cfg.close! if cfg + pid = File.read(@pid.path) + pid = pid.to_i + assert_operator pid, :>, 0 + Process.kill(:QUIT, pid) + poke_until_dead pid + @pid.close! + end end |