test_watcher: fix for Ruby trunk r40195 and later
[raindrops.git] / test / test_watcher.rb
blob70e8e7505e0a7b93da4c5ee670e1630ee9d20357
1 # -*- encoding: binary -*-
2 require "test/unit"
3 require "rack"
4 require "raindrops"
6 class TestWatcher < Test::Unit::TestCase
7   TEST_ADDR = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
8   def check_headers(headers)
9     %w(X-Count X-Std-Dev X-Min X-Max X-Mean
10        X-Outliers-Low X-Outliers-Low X-Last-Reset).each { |x|
11       assert_kind_of String, headers[x], "#{x} missing"
12     }
13   end
15   def teardown
16     @app.shutdown
17     @ios.each { |io| io.close unless io.closed? }
18   end
20   def setup
21     @ios = []
22     @srv = TCPServer.new TEST_ADDR, 0
23     @ios << @srv
24     @port = @srv.addr[1]
25     @client = TCPSocket.new TEST_ADDR, @port
26     @addr = "#{TEST_ADDR}:#{@port}"
27     @ios << @client
28     @app = Raindrops::Watcher.new :delay => 0.001
29     @req = Rack::MockRequest.new @app
30   end
32   def test_index
33     resp = @req.get "/"
34     assert_equal 200, resp.status.to_i
35     t = Time.parse resp.headers["Last-Modified"]
36     assert_in_delta Time.now.to_f, t.to_f, 2.0
37   end
39   def test_active_txt
40     resp = @req.get "/active/#@addr.txt"
41     assert_equal 200, resp.status.to_i
42     assert_equal "text/plain", resp.headers["Content-Type"]
43     check_headers(resp.headers)
44   end
46   def test_invalid
47     assert_nothing_raised do
48       @req.get("/active/666.666.666.666%3A666.txt")
49       @req.get("/queued/666.666.666.666%3A666.txt")
50       @req.get("/active/666.666.666.666%3A666.html")
51       @req.get("/queued/666.666.666.666%3A666.html")
52     end
53     addr = @app.instance_eval do
54       @peak_active.keys + @peak_queued.keys +
55          @resets.keys + @active.keys + @queued.keys
56     end
57     assert addr.grep(/666\.666\.666\.666/).empty?, addr.inspect
58   end
60   def test_active_html
61     resp = @req.get "/active/#@addr.html"
62     assert_equal 200, resp.status.to_i
63     assert_equal "text/html", resp.headers["Content-Type"]
64     check_headers(resp.headers)
65   end
67   def test_queued_txt
68     resp = @req.get "/queued/#@addr.txt"
69     assert_equal 200, resp.status.to_i
70     assert_equal "text/plain", resp.headers["Content-Type"]
71     check_headers(resp.headers)
72   end
74   def test_queued_html
75     resp = @req.get "/queued/#@addr.html"
76     assert_equal 200, resp.status.to_i
77     assert_equal "text/html", resp.headers["Content-Type"]
78     check_headers(resp.headers)
79   end
81   def test_reset
82     resp = @req.post "/reset/#@addr"
83     assert_equal 302, resp.status.to_i
84   end
86   def test_tail
87     env = @req.class.env_for "/tail/#@addr.txt"
88     status, headers, body = @app.call env
89     assert_equal "text/plain", headers["Content-Type"]
90     assert_equal 200, status.to_i
91     tmp = []
92     body.each do |x|
93       assert_kind_of String, x
94       tmp << x
95       break if tmp.size > 1
96     end
97   end
99   def test_tail_queued_min
100     env = @req.class.env_for "/tail/#@addr.txt?queued_min=1"
101     status, headers, body = @app.call env
102     assert_equal "text/plain", headers["Content-Type"]
103     assert_equal 200, status.to_i
104     tmp = []
105     body.each do |x|
106       tmp = TCPSocket.new TEST_ADDR, @port
107       @ios << tmp
108       assert_kind_of String, x
109       assert_equal 1, x.strip.split(/\s+/).last.to_i
110       break
111     end
112   end
114   def test_x_current_header
115     env = @req.class.env_for "/active/#@addr.txt"
116     status, headers, body = @app.call(env)
117     assert_equal "0", headers["X-Current"], headers.inspect
119     env = @req.class.env_for "/queued/#@addr.txt"
120     status, headers, body = @app.call(env)
121     assert_equal "1", headers["X-Current"], headers.inspect
123     @ios << @srv.accept
124     sleep 0.1
126     env = @req.class.env_for "/queued/#@addr.txt"
127     status, headers, body = @app.call(env)
128     assert_equal "0", headers["X-Current"], headers.inspect
130     env = @req.class.env_for "/active/#@addr.txt"
131     status, headers, body = @app.call(env)
132     assert_equal "1", headers["X-Current"], headers.inspect
133   end
135   def test_peaks
136     env = @req.class.env_for "/active/#@addr.txt"
137     status, headers, body = @app.call(env.dup)
138     start = headers["X-First-Peak-At"]
139     assert headers["X-First-Peak-At"], headers.inspect
140     assert headers["X-Last-Peak-At"], headers.inspect
141     assert_nothing_raised { Time.parse(headers["X-First-Peak-At"]) }
142     assert_nothing_raised { Time.parse(headers["X-Last-Peak-At"]) }
143     before = headers["X-Last-Peak-At"]
145     env = @req.class.env_for "/queued/#@addr.txt"
146     status, headers, body = @app.call(env)
147     assert_nothing_raised { Time.parse(headers["X-First-Peak-At"]) }
148     assert_nothing_raised { Time.parse(headers["X-Last-Peak-At"]) }
149     assert_equal before, headers["X-Last-Peak-At"], "should not change"
151     sleep 2
152     env = @req.class.env_for "/active/#@addr.txt"
153     status, headers, body = @app.call(env.dup)
154     assert_equal before, headers["X-Last-Peak-At"], headers.inspect
156     @ios << @srv.accept
157     begin
158       @srv.accept_nonblock
159       assert false, "we should not get here"
160     rescue => e
161       assert_kind_of Errno::EAGAIN, e
162     end
163     sleep 0.1
164     env = @req.class.env_for "/queued/#@addr.txt"
165     status, headers, body = @app.call(env.dup)
166     assert headers["X-Last-Peak-At"], headers.inspect
167     assert_nothing_raised { Time.parse(headers["X-Last-Peak-At"]) }
168     assert before != headers["X-Last-Peak-At"]
170     queued_before = headers["X-Last-Peak-At"]
172     sleep 2
174     env = @req.class.env_for "/queued/#@addr.txt"
175     status, headers, body = @app.call(env)
176     assert_equal "0", headers["X-Current"]
177     assert_nothing_raised { Time.parse(headers["X-Last-Peak-At"]) }
178     assert_equal queued_before, headers["X-Last-Peak-At"], "should not change"
179     assert_equal start, headers["X-First-Peak-At"]
180   end
181 end if RUBY_PLATFORM =~ /linux/