diff options
Diffstat (limited to 'test/http.rb')
-rw-r--r-- | test/http.rb | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/test/http.rb b/test/http.rb index df51836..b1fd3b3 100644 --- a/test/http.rb +++ b/test/http.rb @@ -6,7 +6,7 @@ require 'test/test_helper' require 'digest/md5' require 'net/http' require 'time' -$stderr.sync = $stdout.sync = Thread.abort_on_exception = true +require 'timeout' class TestHTTP < Test::Unit::TestCase def setup @@ -221,4 +221,69 @@ class TestHTTP < Test::Unit::TestCase buf = @client.readpartial(666) assert_match %r{\AHTTP/1\.1 400 Bad Request\r\n}, buf end + + def test_iosem_concurrency + fifo = "#@tmpdir/dev666/fifo.%u.fid" + Dir.mkdir("#@tmpdir/dev666") + Dir.mkdir("#@tmpdir/dev333") + File.open("#@tmpdir/dev333/fast.fid", "w") { |fp| fp.write('.') } + File.open("#@tmpdir/dev666/fast.fid", "w") { |fp| fp.write('.') } + + # create 10 threads which are blocked on the FIFO read + nr = 10 + nr.times do |i| + assert system("mkfifo", fifo % i), "mkfifo #{fifo % i}" + end + threads = [] + nr.times do |i| + thr = Thread.new(i) do |_i| + res = nil + Net::HTTP.start(@host, @port) do |http| + res = http.request(Net::HTTP::Get.new("/dev666/fifo.%u.fid" % _i)) + end + res + end + threads << thr + end + + # start a fast request to the bogged down device, it should get queued + # FIXME: still racy + t_yield + @client.write("GET /dev666/fast.fid HTTP/1.0\r\n") + t_yield + @client.write("\r\n") + + # fast request to a free device + Net::HTTP.start(@host, @port) do |http| + res = http.request(Net::HTTP::Get.new("/dev333/fast.fid")) + assert_equal 200, res.code.to_i + end + + # slow device should still be stuck + assert_equal nil, IO.select([@client], nil, nil, 2) + cr = Thread.new do + val = @client.read + [ val, Time.now ] + end + wr_start = Time.now + + # wake up the blocked threads + writer = Thread.new do + nr.times do |i| + File.open(fifo % i, "w") { |fp| fp.write(i.to_s) } + end + end + + # blocked threads return + threads.each do |t| + assert_equal 403, t.value.code.to_i + end + writer.join + + # fast device should be readable, now + fast_response, fast_finish = Timeout.timeout(5) { cr.value } + assert_match(%r{\AHTTP/1\.1 200 OK}, fast_response) + assert_match(%r{\r\n\r\n\.\z}, fast_response) + assert_operator fast_finish, :>, wr_start + end end |