about summary refs log tree commit homepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/benchmark/big_request.rb11
-rw-r--r--test/benchmark/request.rb9
-rw-r--r--test/benchmark/response.rb1
-rw-r--r--test/tools/trickletest.rb45
-rw-r--r--test/unit/test_request.rb5
-rw-r--r--test/unit/test_signals.rb83
6 files changed, 106 insertions, 48 deletions
diff --git a/test/benchmark/big_request.rb b/test/benchmark/big_request.rb
index 5f2111b..a250c62 100644
--- a/test/benchmark/big_request.rb
+++ b/test/benchmark/big_request.rb
@@ -8,7 +8,11 @@ length = bs * count
 slice = (' ' * bs).freeze
 
 big = Tempfile.new('')
-def big.unicorn_peeraddr; '127.0.0.1'; end
+
+def big.unicorn_peeraddr # old versions of Unicorn used this
+  '127.0.0.1'
+end
+
 big.syswrite(
 "PUT /hello/world/puturl?abcd=efg&hi#anchor HTTP/1.0\r\n" \
 "Host: localhost\r\n" \
@@ -22,6 +26,11 @@ big.fsync
 
 include Unicorn
 request = HttpRequest.new(Logger.new($stderr))
+unless request.respond_to?(:reset)
+  def request.reset
+    # no-op
+  end
+end
 
 Benchmark.bmbm do |x|
   x.report("big") do
diff --git a/test/benchmark/request.rb b/test/benchmark/request.rb
index 67266cb..fc7822c 100644
--- a/test/benchmark/request.rb
+++ b/test/benchmark/request.rb
@@ -10,6 +10,9 @@ class TestClient
     buf.replace(@response)
   end
 
+  alias readpartial sysread
+
+  # old versions of Unicorn used this
   def unicorn_peeraddr
     '127.0.0.1'
   end
@@ -31,6 +34,12 @@ medium = TestClient.new([
 
 include Unicorn
 request = HttpRequest.new(Logger.new($stderr))
+unless request.respond_to?(:reset)
+  def request.reset
+    # no-op
+  end
+end
+
 Benchmark.bmbm do |x|
   x.report("small") do
     for i in 1..nr
diff --git a/test/benchmark/response.rb b/test/benchmark/response.rb
index 0ff0ac2..cb7397b 100644
--- a/test/benchmark/response.rb
+++ b/test/benchmark/response.rb
@@ -3,6 +3,7 @@ require 'unicorn'
 
 class NullWriter
   def syswrite(buf); buf.size; end
+  alias write syswrite
   def close; end
 end
 
diff --git a/test/tools/trickletest.rb b/test/tools/trickletest.rb
deleted file mode 100644
index e19ed71..0000000
--- a/test/tools/trickletest.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require 'socket'
-require 'stringio'
-
-def do_test(st, chunk)
-  s = TCPSocket.new('127.0.0.1',ARGV[0].to_i);
-  req = StringIO.new(st)
-  nout = 0
-  randstop = rand(st.length / 10)
-  STDERR.puts "stopping after: #{randstop}"
-
-  begin
-    while data = req.read(chunk)
-      nout += s.write(data)
-      s.flush
-      sleep 0.1
-      if nout > randstop
-        STDERR.puts "BANG! after #{nout} bytes."
-        break
-      end
-    end
-  rescue Object => e
-    STDERR.puts "ERROR: #{e}"
-  ensure
-    s.close
-  end
-end
-
-content = "-" * (1024 * 240)
-st = "GET / HTTP/1.1\r\nHost: www.zedshaw.com\r\nContent-Type: text/plain\r\nContent-Length: #{content.length}\r\n\r\n#{content}"
-
-puts "length: #{content.length}"
-
-threads = []
-ARGV[1].to_i.times do
-  t = Thread.new do
-    size = 100
-    puts ">>>> #{size} sized chunks"
-    do_test(st, size)
-  end
-
-  t.abort_on_exception = true
-  threads << t
-end
-
-threads.each {|t|  t.join}
diff --git a/test/unit/test_request.rb b/test/unit/test_request.rb
index 060da24..0bfff7d 100644
--- a/test/unit/test_request.rb
+++ b/test/unit/test_request.rb
@@ -14,7 +14,9 @@ include Unicorn
 
 class RequestTest < Test::Unit::TestCase
 
-  class MockRequest < StringIO; end
+  class MockRequest < StringIO
+    alias_method :readpartial, :sysread
+  end
 
   def setup
     @request = HttpRequest.new(Logger.new($stderr))
@@ -75,7 +77,6 @@ class RequestTest < Test::Unit::TestCase
       client = MockRequest.new("GET #{abs_uri} HTTP/1.1\r\n" \
                                "Host: foo\r\n\r\n")
       assert_raises(HttpParserError) { @request.read(client) }
-      @request.reset
     end
   end
 
diff --git a/test/unit/test_signals.rb b/test/unit/test_signals.rb
index bedce01..ef66ed6 100644
--- a/test/unit/test_signals.rb
+++ b/test/unit/test_signals.rb
@@ -37,6 +37,87 @@ class SignalsTest < Test::Unit::TestCase
     @server = nil
   end
 
+  def test_worker_dies_on_dead_master
+    pid = fork {
+      app = lambda { |env| [ 200, {'X-Pid' => "#$$" }, [] ] }
+      opts = @server_opts.merge(:timeout => 3)
+      redirect_test_io { HttpServer.new(app, opts).start.join }
+    }
+    child = sock = buf = t0 = nil
+    assert_nothing_raised do
+      wait_workers_ready("test_stderr.#{pid}.log", 1)
+      sock = TCPSocket.new('127.0.0.1', @port)
+      sock.syswrite("GET / HTTP/1.0\r\n\r\n")
+      buf = sock.readpartial(4096)
+      sock.close
+      buf =~ /\bX-Pid: (\d+)\b/ or raise Exception
+      child = $1.to_i
+      wait_master_ready("test_stderr.#{pid}.log")
+      Process.kill(:KILL, pid)
+      Process.waitpid(pid)
+      t0 = Time.now
+    end
+    assert child
+    assert t0
+    assert_raises(Errno::ESRCH) { loop { Process.kill(0, child); sleep 0.2 } }
+    assert((Time.now - t0) < 60)
+  end
+
+  def test_sleepy_kill
+    rd, wr = IO.pipe
+    pid = fork {
+      rd.close
+      app = lambda { |env| wr.syswrite('.'); sleep; [ 200, {}, [] ] }
+      redirect_test_io { HttpServer.new(app, @server_opts).start.join }
+    }
+    sock = buf = nil
+    wr.close
+    assert_nothing_raised do
+      wait_workers_ready("test_stderr.#{pid}.log", 1)
+      sock = TCPSocket.new('127.0.0.1', @port)
+      sock.syswrite("GET / HTTP/1.0\r\n\r\n")
+      buf = rd.readpartial(1)
+      wait_master_ready("test_stderr.#{pid}.log")
+      Process.kill(:INT, pid)
+      Process.waitpid(pid)
+    end
+    assert_equal '.', buf
+    buf = nil
+    assert_raises(EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,
+                  Errno::EBADF) do
+      buf = sock.sysread(4096)
+    end
+    assert_nil buf
+    ensure
+  end
+
+  def test_timeout_slow_response
+    pid = fork {
+      app = lambda { |env| sleep }
+      opts = @server_opts.merge(:timeout => 3)
+      redirect_test_io { HttpServer.new(app, opts).start.join }
+    }
+    t0 = Time.now
+    sock = nil
+    assert_nothing_raised do
+      wait_workers_ready("test_stderr.#{pid}.log", 1)
+      sock = TCPSocket.new('127.0.0.1', @port)
+      sock.syswrite("GET / HTTP/1.0\r\n\r\n")
+    end
+
+    buf = nil
+    assert_raises(EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,
+                  Errno::EBADF) do
+      buf = sock.sysread(4096)
+    end
+    diff = Time.now - t0
+    assert_nil buf
+    assert diff > 1.0, "diff was #{diff.inspect}"
+    assert diff < 60.0
+    ensure
+      Process.kill(:QUIT, pid) rescue nil
+  end
+
   def test_response_write
     app = lambda { |env|
       [ 200, { 'Content-Type' => 'text/plain', 'X-Pid' => Process.pid.to_s },
@@ -45,6 +126,7 @@ class SignalsTest < Test::Unit::TestCase
     redirect_test_io { @server = HttpServer.new(app, @server_opts).start }
     sock = nil
     assert_nothing_raised do
+      wait_workers_ready("test_stderr.#{$$}.log", 1)
       sock = TCPSocket.new('127.0.0.1', @port)
       sock.syswrite("GET / HTTP/1.0\r\n\r\n")
     end
@@ -82,6 +164,7 @@ class SignalsTest < Test::Unit::TestCase
     pid = nil
 
     assert_nothing_raised do
+      wait_workers_ready("test_stderr.#{$$}.log", 1)
       sock = TCPSocket.new('127.0.0.1', @port)
       sock.syswrite("GET / HTTP/1.0\r\n\r\n")
       pid = sock.sysread(4096)[/\r\nX-Pid: (\d+)\r\n/, 1].to_i