Mongrel.run(app, opts)
[unicorn.git] / test / unit / test_threading.rb
blobd4ad68345c03b5ae350b0167930ab4a16906c278
1 root_dir = File.join(File.dirname(__FILE__), "../..")
2 require File.join(root_dir, "test/test_helper")
4 include Mongrel
6 class FakeHandler
7   @@concurrent_threads = 0
8   @@threads = 0
9   
10   def self.max_concurrent_threads
11     @@threads ||= 0
12   end
13   
14   def initialize
15     super
16     @@mutex = Mutex.new
17   end
18   
19   def call(env)
20     @@mutex.synchronize do
21       @@concurrent_threads += 1 # !!! same for += and -=
22       @@threads = [@@concurrent_threads, @@threads].max
23     end
24     
25     sleep(0.1)
26     [200, {'Content-Type' => 'text/plain'}, ['hello!']]
27   ensure
28     @@mutex.synchronize { @@concurrent_threads -= 1 }
29   end
30 end
32 class ThreadingTest < Test::Unit::TestCase
33   def setup
34     @valid_request = "GET / HTTP/1.1\r\nHost: www.google.com\r\nContent-Type: text/plain\r\n\r\n"
35     @port = process_based_port
36     @app = Rack::URLMap.new('/test' => FakeHandler.new)
37     @threads = 4
38     redirect_test_io { @server = HttpServer.new(@app, :Host => "127.0.0.1", :Port => @port, :Max_concurrent_threads => @threads) }    
39     redirect_test_io { @server.start }
40   end
42   def teardown
43     redirect_test_io { @server.stop(true) }
44   end
46   def test_server_respects_max_concurrent_threads_option
47     threads = []
48     (@threads * 3).times do
49       threads << Thread.new do
50         send_data_over_socket("GET /test HTTP/1.1\r\nHost: localhost\r\nContent-Type: text/plain\r\n\r\n")
51       end
52     end
53     while threads.any? { |thread| thread.alive? }
54       sleep(0)
55     end
56     assert_equal @threads, FakeHandler.max_concurrent_threads
57   end
58   
59   private 
60   
61   def send_data_over_socket(string)
62     socket = TCPSocket.new("127.0.0.1", @port)
63     request = StringIO.new(string)
65     while data = request.read(8)
66       socket.write(data)
67       socket.flush
68       sleep(0)
69     end
70     sleep(0)
71     socket.write(" ") # Some platforms only raise the exception on attempted write
72     socket.flush
73   end
74 end