about summary refs log tree commit homepage
path: root/test
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-03-31 19:15:50 -0700
committerEric Wong <normalperson@yhbt.net>2009-03-31 19:15:50 -0700
commit71c8ce651166b49178676f1c37723aa34c4ef9e5 (patch)
treed2cae4c00a386d8caa46c7b6794b99bb2dbc16fa /test
parentaba465e9d196737b07786a759ba320c89ae31c2e (diff)
downloadunicorn-71c8ce651166b49178676f1c37723aa34c4ef9e5.tar.gz
Diffstat (limited to 'test')
-rw-r--r--test/exec/test_exec.rb148
-rw-r--r--test/rails/test_rails.rb10
-rw-r--r--test/test_helper.rb151
3 files changed, 155 insertions, 154 deletions
diff --git a/test/exec/test_exec.rb b/test/exec/test_exec.rb
index 2d0528f..d7c8206 100644
--- a/test/exec/test_exec.rb
+++ b/test/exec/test_exec.rb
@@ -1,28 +1,19 @@
 # Copyright (c) 2009 Eric Wong
-STDIN.sync = STDOUT.sync = STDERR.sync = true
 require 'test/test_helper'
-require 'pathname'
-require 'tempfile'
-require 'fileutils'
 
 do_test = true
-DEFAULT_TRIES = 1000
-DEFAULT_RES = 0.2
-
 $unicorn_bin = ENV['UNICORN_TEST_BIN'] || "unicorn"
 redirect_test_io do
   do_test = system($unicorn_bin, '-v')
 end
 
 unless do_test
-  STDERR.puts "#{$unicorn_bin} not found in PATH=#{ENV['PATH']}, " \
-              "skipping this test"
+  warn "#{$unicorn_bin} not found in PATH=#{ENV['PATH']}, " \
+       "skipping this test"
 end
 
-begin
-  require 'rack'
-rescue LoadError
-  STDERR.puts "Unable to load Rack, skipping this test"
+unless try_require('rack')
+  warn "Unable to load Rack, skipping this test"
   do_test = false
 end
 
@@ -476,135 +467,4 @@ end
     reexec_usr2_quit_test(new_pid, pid_file)
   end
 
-  private
-
-    # sometimes the server may not come up right away
-    def retry_hit(uris = [])
-      tries = DEFAULT_TRIES
-      begin
-        hit(uris)
-      rescue Errno::ECONNREFUSED => err
-        if (tries -= 1) > 0
-          sleep DEFAULT_RES
-          retry
-        end
-        raise err
-      end
-    end
-
-    def assert_shutdown(pid)
-      wait_master_ready("#{@tmpdir}/test_stderr.#{pid}.log")
-      assert_nothing_raised { Process.kill(:QUIT, pid) }
-      status = nil
-      assert_nothing_raised { pid, status = Process.waitpid2(pid) }
-      assert status.success?, "exited successfully"
-    end
-
-    def wait_workers_ready(path, nr_workers)
-      tries = DEFAULT_TRIES
-      lines = []
-      while (tries -= 1) > 0
-        begin
-          lines = File.readlines(path).grep(/worker=\d+ ready/)
-          lines.size == nr_workers and return
-        rescue Errno::ENOENT
-        end
-        sleep DEFAULT_RES
-      end
-      raise "#{nr_workers} workers never became ready:" \
-            "\n\t#{lines.join("\n\t")}\n"
-    end
-
-    def wait_master_ready(master_log)
-      tries = DEFAULT_TRIES
-      while (tries -= 1) > 0
-        begin
-          File.readlines(master_log).grep(/master process ready/)[0] and return
-        rescue Errno::ENOENT
-        end
-        sleep DEFAULT_RES
-      end
-      raise "master process never became ready"
-    end
-
-    def reexec_usr2_quit_test(pid, pid_file)
-      assert File.exist?(pid_file), "pid file OK"
-      assert ! File.exist?("#{pid_file}.oldbin"), "oldbin pid file"
-      assert_nothing_raised { Process.kill(:USR2, pid) }
-      assert_nothing_raised { retry_hit(["http://#{@addr}:#{@port}/"]) }
-      wait_for_file("#{pid_file}.oldbin")
-      wait_for_file(pid_file)
-
-      old_pid = File.read("#{pid_file}.oldbin").to_i
-      new_pid = File.read(pid_file).to_i
-
-      # kill old master process
-      assert_not_equal pid, new_pid
-      assert_equal pid, old_pid
-      assert_nothing_raised { Process.kill(:QUIT, old_pid) }
-      assert_nothing_raised { retry_hit(["http://#{@addr}:#{@port}/"]) }
-      wait_for_death(old_pid)
-      assert_equal new_pid, File.read(pid_file).to_i
-      assert_nothing_raised { retry_hit(["http://#{@addr}:#{@port}/"]) }
-      assert_nothing_raised { Process.kill(:QUIT, new_pid) }
-    end
-
-    def reexec_basic_test(pid, pid_file)
-      results = retry_hit(["http://#{@addr}:#{@port}/"])
-      assert_equal String, results[0].class
-      assert_nothing_raised { Process.kill(0, pid) }
-      master_log = "#{@tmpdir}/test_stderr.#{pid}.log"
-      wait_master_ready(master_log)
-      File.truncate(master_log, 0)
-      nr = 50
-      kill_point = 2
-      assert_nothing_raised do
-        nr.times do |i|
-          hit(["http://#{@addr}:#{@port}/#{i}"])
-          i == kill_point and Process.kill(:HUP, pid)
-        end
-      end
-      wait_master_ready(master_log)
-      assert File.exist?(pid_file), "pid=#{pid_file} exists"
-      new_pid = File.read(pid_file).to_i
-      assert_not_equal pid, new_pid
-      assert_nothing_raised { Process.kill(0, new_pid) }
-      assert_nothing_raised { Process.kill(:QUIT, new_pid) }
-    end
-
-    def wait_for_file(path)
-      tries = DEFAULT_TRIES
-      while (tries -= 1) > 0 && ! File.exist?(path)
-        sleep DEFAULT_RES
-      end
-      assert File.exist?(path), "path=#{path} exists #{caller.inspect}"
-    end
-
-    def xfork(&block)
-      fork do
-        ObjectSpace.each_object(Tempfile) do |tmp|
-          ObjectSpace.undefine_finalizer(tmp)
-        end
-        yield
-      end
-    end
-
-    # can't waitpid on detached processes
-    def wait_for_death(pid)
-      tries = DEFAULT_TRIES
-      while (tries -= 1) > 0
-        begin
-          Process.kill(0, pid)
-          begin
-            Process.waitpid(pid, Process::WNOHANG)
-          rescue Errno::ECHILD
-          end
-          sleep(DEFAULT_RES)
-        rescue Errno::ESRCH
-          return
-        end
-      end
-      raise "PID:#{pid} never died!"
-    end
-
 end if do_test
diff --git a/test/rails/test_rails.rb b/test/rails/test_rails.rb
index aa0d300..2815734 100644
--- a/test/rails/test_rails.rb
+++ b/test/rails/test_rails.rb
@@ -1,14 +1,8 @@
 # Copyright (c) 2009 Eric Wong
-STDIN.sync = STDOUT.sync = STDERR.sync = true
 require 'test/test_helper'
-require 'pathname'
-require 'tempfile'
-require 'fileutils'
 
 # don't call exit(0) since it may be run under rake (but gmake is recommended)
 do_test = true
-DEFAULT_TRIES = 1000
-DEFAULT_RES = 0.2
 
 $unicorn_rails_bin = ENV['UNICORN_RAILS_TEST_BIN'] || "unicorn_rails"
 redirect_test_io { do_test = system($unicorn_rails_bin, '-v') }
@@ -92,7 +86,7 @@ logger Logger.new('#{COMMON_TMP.path}')
     redirect_test_io do
       pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" }
     end
-    sleep 1 # HACK
+    wait_master_ready("test_stderr.#$$.log")
     tmp_dirs.each { |dir| assert(File.directory?("tmp/#{dir}")) }
     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo"))
     assert_equal "FOO\n", res.body
@@ -111,7 +105,7 @@ logger Logger.new('#{COMMON_TMP.path}')
     redirect_test_io do
       pid = fork { exec 'unicorn_rails', "-l#@addr:#@port", '-P/poo' }
     end
-    sleep 1 # HACK
+    wait_master_ready("test_stderr.#$$.log")
     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/poo/foo"))
     # p res
     # p res.body
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 4243606..37625ec 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -4,9 +4,16 @@
 # Additional work donated by contributors.  See http://mongrel.rubyforge.org/attributions.html
 # for more information.
 
+STDIN.sync = STDOUT.sync = STDERR.sync = true # buffering makes debugging hard
+
+# Some tests watch a log file or a pid file to spring up to check state
+# Can't rely on inotify on non-Linux and logging to a pipe makes things
+# more complicated
+DEFAULT_TRIES = 1000
+DEFAULT_RES = 0.2
 
 HERE = File.dirname(__FILE__) unless defined?(HERE)
-%w(lib ext bin test).each do |dir|
+%w(lib ext).each do |dir|
   $LOAD_PATH.unshift "#{HERE}/../#{dir}"
 end
 
@@ -15,8 +22,10 @@ require 'net/http'
 require 'digest/sha1'
 require 'uri'
 require 'stringio'
+require 'pathname'
+require 'tempfile'
+require 'fileutils'
 require 'unicorn'
-require 'tmpdir'
 
 if ENV['DEBUG']
   require 'ruby-debug'
@@ -112,3 +121,141 @@ def unused_port(addr = '127.0.0.1')
   sock.close rescue nil
   port
 end
+
+def try_require(lib)
+  begin
+    require lib
+    true
+  rescue LoadError
+    false
+  end
+end
+
+# sometimes the server may not come up right away
+def retry_hit(uris = [])
+  tries = DEFAULT_TRIES
+  begin
+    hit(uris)
+  rescue Errno::ECONNREFUSED => err
+    if (tries -= 1) > 0
+      sleep DEFAULT_RES
+      retry
+    end
+    raise err
+  end
+end
+
+def assert_shutdown(pid)
+  wait_master_ready("test_stderr.#{pid}.log")
+  assert_nothing_raised { Process.kill(:QUIT, pid) }
+  status = nil
+  assert_nothing_raised { pid, status = Process.waitpid2(pid) }
+  assert status.success?, "exited successfully"
+end
+
+def wait_workers_ready(path, nr_workers)
+  tries = DEFAULT_TRIES
+  lines = []
+  while (tries -= 1) > 0
+    begin
+      lines = File.readlines(path).grep(/worker=\d+ ready/)
+      lines.size == nr_workers and return
+    rescue Errno::ENOENT
+    end
+    sleep DEFAULT_RES
+  end
+  raise "#{nr_workers} workers never became ready:" \
+        "\n\t#{lines.join("\n\t")}\n"
+end
+
+def wait_master_ready(master_log)
+  tries = DEFAULT_TRIES
+  while (tries -= 1) > 0
+    begin
+      File.readlines(master_log).grep(/master process ready/)[0] and return
+    rescue Errno::ENOENT
+    end
+    sleep DEFAULT_RES
+  end
+  raise "master process never became ready"
+end
+
+def reexec_usr2_quit_test(pid, pid_file)
+  assert File.exist?(pid_file), "pid file OK"
+  assert ! File.exist?("#{pid_file}.oldbin"), "oldbin pid file"
+  assert_nothing_raised { Process.kill(:USR2, pid) }
+  assert_nothing_raised { retry_hit(["http://#{@addr}:#{@port}/"]) }
+  wait_for_file("#{pid_file}.oldbin")
+  wait_for_file(pid_file)
+
+  old_pid = File.read("#{pid_file}.oldbin").to_i
+  new_pid = File.read(pid_file).to_i
+
+  # kill old master process
+  assert_not_equal pid, new_pid
+  assert_equal pid, old_pid
+  assert_nothing_raised { Process.kill(:QUIT, old_pid) }
+  assert_nothing_raised { retry_hit(["http://#{@addr}:#{@port}/"]) }
+  wait_for_death(old_pid)
+  assert_equal new_pid, File.read(pid_file).to_i
+  assert_nothing_raised { retry_hit(["http://#{@addr}:#{@port}/"]) }
+  assert_nothing_raised { Process.kill(:QUIT, new_pid) }
+end
+
+def reexec_basic_test(pid, pid_file)
+  results = retry_hit(["http://#{@addr}:#{@port}/"])
+  assert_equal String, results[0].class
+  assert_nothing_raised { Process.kill(0, pid) }
+  master_log = "#{@tmpdir}/test_stderr.#{pid}.log"
+  wait_master_ready(master_log)
+  File.truncate(master_log, 0)
+  nr = 50
+  kill_point = 2
+  assert_nothing_raised do
+    nr.times do |i|
+      hit(["http://#{@addr}:#{@port}/#{i}"])
+      i == kill_point and Process.kill(:HUP, pid)
+    end
+  end
+  wait_master_ready(master_log)
+  assert File.exist?(pid_file), "pid=#{pid_file} exists"
+  new_pid = File.read(pid_file).to_i
+  assert_not_equal pid, new_pid
+  assert_nothing_raised { Process.kill(0, new_pid) }
+  assert_nothing_raised { Process.kill(:QUIT, new_pid) }
+end
+
+def wait_for_file(path)
+  tries = DEFAULT_TRIES
+  while (tries -= 1) > 0 && ! File.exist?(path)
+    sleep DEFAULT_RES
+  end
+  assert File.exist?(path), "path=#{path} exists #{caller.inspect}"
+end
+
+def xfork(&block)
+  fork do
+    ObjectSpace.each_object(Tempfile) do |tmp|
+      ObjectSpace.undefine_finalizer(tmp)
+    end
+    yield
+  end
+end
+
+# can't waitpid on detached processes
+def wait_for_death(pid)
+  tries = DEFAULT_TRIES
+  while (tries -= 1) > 0
+    begin
+      Process.kill(0, pid)
+      begin
+        Process.waitpid(pid, Process::WNOHANG)
+      rescue Errno::ECHILD
+      end
+      sleep(DEFAULT_RES)
+    rescue Errno::ESRCH
+      return
+    end
+  end
+  raise "PID:#{pid} never died!"
+end