about summary refs log tree commit homepage
path: root/test
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-04-01 20:13:21 -0700
committerEric Wong <normalperson@yhbt.net>2009-04-01 21:34:21 -0700
commitac01d8c83b6a3e0d9d0883d9df17f45e208ac101 (patch)
tree54d1cef97e423fdf7fb169f52fcb7415cd125c82 /test
parente3a6639e270157c4fdc4112a6996c9e7d74acedd (diff)
downloadunicorn-ac01d8c83b6a3e0d9d0883d9df17f45e208ac101.tar.gz
We'll allow before_exec to override that setting, however.

There are cases where someone setting
Logger.new("/path/to/file") will create new file descriptors in
the master process.  This will prevent FD leakage
and a test case (for Linux only) proves it.
Diffstat (limited to 'test')
-rw-r--r--test/exec/test_exec.rb63
1 files changed, 63 insertions, 0 deletions
diff --git a/test/exec/test_exec.rb b/test/exec/test_exec.rb
index 78f452b..6c3d282 100644
--- a/test/exec/test_exec.rb
+++ b/test/exec/test_exec.rb
@@ -499,4 +499,67 @@ end
     reexec_usr2_quit_test(new_pid, pid_file)
   end
 
+  def test_reexec_fd_leak
+    unless RUBY_PLATFORM =~ /linux/ # Solaris may work, too, but I forget...
+      warn "FD leak test only works on Linux at the moment"
+      return
+    end
+    pid_file = "#{@tmpdir}/test.pid"
+    log = Tempfile.new('unicorn_test_log')
+    log.sync = true
+    ucfg = Tempfile.new('unicorn_test_config')
+    ucfg.syswrite("pid \"#{pid_file}\"\n")
+    ucfg.syswrite("logger Logger.new('#{log.path}')\n")
+    ucfg.syswrite("stderr_path '#{log.path}'\n")
+    ucfg.syswrite("stdout_path '#{log.path}'\n")
+    ucfg.close
+
+    File.open("config.ru", "wb") { |fp| fp.syswrite(HI) }
+    pid = xfork do
+      redirect_test_io do
+        exec($unicorn_bin, "-D", "-l#{@addr}:#{@port}", "-c#{ucfg.path}")
+      end
+    end
+
+    wait_master_ready(log.path)
+    wait_for_file(pid_file)
+    orig_pid = pid = File.read(pid_file).to_i
+    orig_fds = `ls -l /proc/#{pid}/fd`.split(/\n/)
+    assert $?.success?
+    expect_size = orig_fds.size
+
+    assert_nothing_raised do
+      Process.kill(:USR2, pid)
+      wait_for_file("#{pid_file}.oldbin")
+      Process.kill(:QUIT, pid)
+    end
+    wait_for_death(pid)
+
+    wait_for_file(pid_file)
+    pid = File.read(pid_file).to_i
+    assert_not_equal orig_pid, pid
+    curr_fds = `ls -l /proc/#{pid}/fd`.split(/\n/)
+    assert $?.success?
+
+    # we could've inherited descriptors the first time around
+    assert expect_size >= curr_fds.size
+    expect_size = curr_fds.size
+
+    assert_nothing_raised do
+      Process.kill(:USR2, pid)
+      wait_for_file("#{pid_file}.oldbin")
+      Process.kill(:QUIT, pid)
+    end
+    wait_for_death(pid)
+
+    wait_for_file(pid_file)
+    pid = File.read(pid_file).to_i
+    curr_fds = `ls -l /proc/#{pid}/fd`.split(/\n/)
+    assert $?.success?
+    assert_equal expect_size, curr_fds.size
+
+    Process.kill(:QUIT, pid)
+    wait_for_death(pid)
+  end
+
 end if do_test