hot_tub 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/pool_spec.rb DELETED
@@ -1,386 +0,0 @@
1
- require 'spec_helper'
2
- describe HotTub::Pool do
3
-
4
- context 'default settings' do
5
- before(:each) do
6
- @pool = HotTub::Pool.new { MocClient.new }
7
- end
8
-
9
- it "should have :size of 5" do
10
- @pool.instance_variable_get(:@size).should eql(5)
11
- end
12
-
13
- it "should have :wait_timeout of 0.5" do
14
- @pool.instance_variable_get(:@wait_timeout).should eql(10)
15
- end
16
-
17
- it "should have set the client" do
18
- @pool.instance_variable_get(:@new_client).call.should be_a(MocClient)
19
- end
20
-
21
- it "should be true" do
22
- @pool.instance_variable_get(:@max_size).should eql(0)
23
- end
24
-
25
- it "should have a HotTub::Reaper" do
26
- @pool.reaper.should be_a(HotTub::Reaper)
27
- end
28
- end
29
-
30
- context 'custom settings' do
31
- before(:each) do
32
- @pool = HotTub::Pool.new(:size => 10, :wait_timeout => 1.0, :max_size => 20) { MocClient.new }
33
- end
34
-
35
- it "should have :size of 5" do
36
- @pool.instance_variable_get(:@size).should eql(10)
37
- end
38
-
39
- it "should have :wait_timeout of 0.5" do
40
- @pool.instance_variable_get(:@wait_timeout).should eql(1.0)
41
- end
42
-
43
- it "should be true" do
44
- @pool.instance_variable_get(:@max_size).should eql(20)
45
- end
46
- end
47
-
48
- describe '#run' do
49
- before(:each) do
50
- @pool = HotTub::Pool.new { MocClient.new}
51
- end
52
-
53
- it "should remove connection from pool when doing work" do
54
- @pool.run do |connection|
55
- @connection = connection
56
- @fetched = @pool.instance_variable_get(:@pool).select{|c| c.object_id == @connection.object_id}.length.should eql(0) # not in pool because its doing work
57
- end
58
- end
59
-
60
- it "should return the connection after use" do
61
- @connection = nil
62
- @pool.run do |connection|
63
- @connection = connection
64
- end
65
- # returned to pool after work was done
66
- @pool.instance_variable_get(:@pool).pop.should eql(@connection)
67
- end
68
-
69
- it "should work" do
70
- result = nil
71
- @pool.run{|clnt| result = clnt.get}
72
- result.should_not be_nil
73
- end
74
-
75
- context 'block not given' do
76
- it "should raise ArgumentError" do
77
- lambda { @pool.run }.should raise_error(ArgumentError)
78
- end
79
- end
80
- end
81
-
82
- describe '#drain!' do
83
- before(:each) do
84
- @pool = HotTub::Pool.new(:size => 5) { MocClient.new }
85
- @pool.instance_variable_set(:@out, [MocClient.new,MocClient.new,MocClient.new])
86
- @pool.instance_variable_set(:@pool, [MocClient.new,MocClient.new,MocClient.new])
87
- end
88
-
89
- context ":close_out" do
90
- it "should reset out" do
91
- @pool.instance_variable_set(:@close_out, true)
92
- @pool.drain!
93
- @pool.instance_variable_get(:@out).length.should eql(0)
94
- end
95
- end
96
-
97
- it "should reset pool" do
98
- @pool.drain!
99
- @pool.instance_variable_get(:@pool).length.should eql(0)
100
- @pool.send(:_total_current_size).should eql(3)
101
- @pool.instance_variable_get(:@out).length.should eql(3)
102
- end
103
- end
104
-
105
- describe '#clean!' do
106
- before(:each) do
107
- @pool = HotTub::Pool.new(:size => 3, :clean => lambda { |clnt| clnt.clean}) { MocClient.new }
108
- end
109
-
110
- it "should clean pool" do
111
- @pool.instance_variable_set(:@pool, [MocClient.new,MocClient.new,MocClient.new])
112
- @pool.instance_variable_get(:@pool).first.cleaned?.should be_false
113
- @pool.clean!
114
- @pool.instance_variable_get(:@pool).each do |clnt|
115
- clnt.cleaned?.should be_true
116
- end
117
- end
118
- end
119
-
120
- describe '#shutdown!' do
121
- before(:each) do
122
- @pool = HotTub::Pool.new(:size => 5) { MocClient.new }
123
- end
124
-
125
- it "should kill reaper" do
126
- @pool.shutdown!
127
- sleep(0.01)
128
- @pool.instance_variable_get(:@reaper).status.should be_false
129
- end
130
-
131
- it "should reset pool" do
132
- @pool.instance_variable_set(:@pool, [MocClient.new,MocClient.new,MocClient.new])
133
- @pool.shutdown!
134
- @pool.instance_variable_get(:@pool).length.should eql(0)
135
- @pool.send(:_total_current_size).should eql(0)
136
- end
137
- end
138
-
139
- context 'private methods' do
140
- before(:each) do
141
- @url = "http://www.testurl123.com/"
142
- @pool = HotTub::Pool.new { MocClient.new}
143
- end
144
-
145
- describe '#client' do
146
- it "should raise HotTub::BlockingTimeout if an available is not found in time"do
147
- @pool.instance_variable_set(:@non_blocking,false)
148
- @pool.instance_variable_set(:@wait_timeout, 0.1)
149
- @pool.stub(:raise_alarm?).and_return(true)
150
- lambda { puts @pool.send(:pop) }.should raise_error(HotTub::Pool::Timeout)
151
- end
152
-
153
- it "should return an instance of the client" do
154
- @pool.send(:client).should be_instance_of(MocClient)
155
- end
156
- end
157
-
158
- describe 'add?' do
159
- it "should be true if @pool_data[:length] is less than desired pool size and
160
- the pool is empty?"do
161
- @pool.instance_variable_set(:@pool,[])
162
- @pool.send(:_add?).should be_true
163
- end
164
-
165
- it "should be false pool has reached pool_size" do
166
- @pool.instance_variable_set(:@size, 5)
167
- @pool.instance_variable_set(:@pool,[1,1,1,1,1])
168
- @pool.send(:_add?).should be_false
169
- end
170
- end
171
-
172
- describe '#_add' do
173
- it "should add client for supplied url"do
174
- pre_add_length = @pool.instance_variable_get(:@pool).length
175
- @pool.send(:_add)
176
- @pool.instance_variable_get(:@pool).length.should be > pre_add_length
177
- end
178
- end
179
-
180
- describe '#push' do
181
- context "client is registered" do
182
- it "should push client back to pool" do
183
- @pool.send(:_add)
184
- clnt = @pool.instance_variable_get(:@pool).pop
185
- @pool.send(:push,clnt)
186
- @pool.instance_variable_get(:@pool).include?(clnt).should be_true
187
- end
188
- end
189
- context "client is nil" do
190
- it "should not push client back to pool" do
191
- @pool.send(:push,nil)
192
- @pool.instance_variable_get(:@pool).include?(nil).should be_false
193
- end
194
- end
195
- end
196
- end
197
-
198
- context ':max_size' do
199
- context 'is default' do
200
- it "should add clients to pool as necessary" do
201
- pool = HotTub::Pool.new({:size => 1}) { MocClient.new }
202
- threads = []
203
- 5.times.each do
204
- threads << Thread.new do
205
- pool.run{|cltn| cltn.get }
206
- end
207
- end
208
- threads.each do |t|
209
- t.join
210
- end
211
- (pool.send(:_total_current_size) > 1).should be_true
212
- end
213
- end
214
- context 'is set' do
215
- it "should not add clients to pool beyond specified size" do
216
- pool = HotTub::Pool.new({:size => 1, :max_size => 1, :wait_timeout => 100}) { MocClient.new }
217
- threads = []
218
- 5.times.each do
219
- threads << Thread.new do
220
- pool.run{|cltn| cltn.get }
221
- end
222
- end
223
- threads.each do |t|
224
- t.join
225
- end
226
- pool.send(:_total_current_size).should eql(1)
227
- end
228
- end
229
- end
230
-
231
- describe '#reap' do
232
- context 'current_size is greater than :size' do
233
- it "should remove a client from the pool" do
234
- pool = HotTub::Pool.new({:size => 1}) { MocClient.new }
235
- pool.instance_variable_set(:@last_activity,(Time.now - 601))
236
- pool.instance_variable_set(:@pool, [MocClient.new,MocClient.new,MocClient.new])
237
- pool.send(:_reap?).should be_true
238
- pool.reaper.wakeup # run the reaper thread
239
- sleep(0.1) # let results
240
- pool.send(:_total_current_size).should eql(1)
241
- pool.instance_variable_get(:@pool).length.should eql(1)
242
- end
243
- end
244
- end
245
-
246
- context 'thread safety' do
247
- it "should work" do
248
- pool = HotTub::Pool.new({:size => 10}) { MocClient.new }
249
- failed = false
250
- lambda {
251
- threads = []
252
- 20.times.each do
253
- threads << Thread.new do
254
- pool.run{|connection| connection.get }
255
- end
256
- end
257
- threads.each do |t|
258
- t.join
259
- end
260
- }.should_not raise_error
261
- (pool.instance_variable_get(:@pool).length >= 10).should be_true # make sure work got done
262
- end
263
- end
264
-
265
- context "other http client" do
266
- before(:each) do
267
- @pool = HotTub::Pool.new(:clean => lambda {|clnt| clnt.clean}) {MocClient.new}
268
- end
269
-
270
- it "should clean connections" do
271
- @pool.run do |clnt|
272
- clnt.cleaned?.should be_true
273
- end
274
- end
275
- end
276
-
277
- context 'integration tests' do
278
- context "blocking" do
279
- before(:each) do
280
- @pool = HotTub::Pool.new(:size => 5, :max_size => 5) {
281
- uri = URI.parse(HotTub::Server.url)
282
- http = Net::HTTP.new(uri.host, uri.port)
283
- http.use_ssl = false
284
- http.start
285
- http
286
- }
287
- end
288
- it "should work" do
289
- result = nil
290
- @pool.run{|clnt|
291
- uri = URI.parse(HotTub::Server.url)
292
- result = clnt.head(uri.path).code
293
- }
294
- result.should eql('200')
295
- end
296
- context 'threads' do
297
- it "should work" do
298
- failed = false
299
- threads = []
300
- lambda { net_http_thread_work(@pool,10, threads) }.should_not raise_error
301
- @pool.reap!
302
- lambda { net_http_thread_work(@pool,20, threads) }.should_not raise_error
303
- @pool.send(:_total_current_size).should eql(5) # make sure the pool grew beyond size
304
- results = threads.collect{ |t| t[:status]}
305
- results.length.should eql(30) # make sure all threads are present
306
- results.uniq.should eql(['200']) # make sure all returned status 200
307
- end
308
- end
309
- end
310
- context "never block without max" do
311
- before(:each) do
312
- @pool = HotTub::Pool.new(:size => 5) {
313
- uri = URI.parse(HotTub::Server.url)
314
- http = Net::HTTP.new(uri.host, uri.port)
315
- http.use_ssl = false
316
- http.start
317
- http
318
- }
319
- end
320
- it "should work" do
321
- result = nil
322
- @pool.run{|clnt|
323
- uri = URI.parse(HotTub::Server.url)
324
- result = clnt.head(uri.path).code
325
- }
326
- result.should eql('200')
327
- end
328
- context 'threads' do
329
- it "should work" do
330
- failed = false
331
- threads = []
332
- lambda { net_http_thread_work(@pool,10, threads) }.should_not raise_error
333
- @pool.reap! # Force reaping to shrink pool back
334
- lambda { net_http_thread_work(@pool,20, threads) }.should_not raise_error
335
- @pool.send(:_total_current_size).should > 5 # make sure the pool grew beyond size
336
- results = threads.collect{ |t| t[:status]}
337
- results.length.should eql(30) # make sure all threads are present
338
- results.uniq.should eql(['200']) # make sure all returned status 200
339
- end
340
- end
341
- end
342
- context "never block with max" do
343
- before(:each) do
344
- @pool = HotTub::Pool.new(:size => 5, :max_size => 10) {
345
- uri = URI.parse(HotTub::Server.url)
346
- http = Net::HTTP.new(uri.host, uri.port)
347
- http.use_ssl = false
348
- http.start
349
- http
350
- }
351
- end
352
- it "should work" do
353
- result = nil
354
- @pool.run{|clnt|
355
- uri = URI.parse(HotTub::Server.url)
356
- result = clnt.head(uri.path).code
357
- }
358
- result.should eql('200')
359
- end
360
- context 'threads' do
361
- it "should work" do
362
- failed = false
363
- threads = []
364
- lambda { net_http_thread_work(@pool,10, threads) }.should_not raise_error
365
- lambda { net_http_thread_work(@pool,20, threads) }.should_not raise_error
366
- @pool.send(:_total_current_size).should > 5 # make sure pool is at max_size
367
- results = threads.collect{ |t| t[:status]}
368
- results.length.should eql(30) # make sure all threads are present
369
- results.uniq.should eql(['200']) # make sure all returned status 200
370
- end
371
- end
372
- end
373
- end
374
-
375
- def net_http_thread_work(pool,thread_count=0, threads=[])
376
- thread_count.times.each do
377
- threads << Thread.new do
378
- uri = URI.parse(HotTub::Server.url)
379
- pool.run{|connection| Thread.current[:status] = connection.head(uri.path).code }
380
- end
381
- end
382
- threads.each do |t|
383
- t.join
384
- end
385
- end
386
- end
data/spec/reaper_spec.rb DELETED
@@ -1,28 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe HotTub::Reaper do
4
- before(:each) do
5
- @pool = MocReaperPool.new
6
- @reaper = @pool.reaper
7
- end
8
- it "should be a HotTub::Reaper Thread" do
9
- @reaper.should be_a(HotTub::Reaper)
10
- @reaper.should be_a(Thread)
11
- end
12
-
13
- it "should reap!" do
14
- @pool.reaped.should be_false
15
- @pool.lets_reap = true
16
- @reaper.wakeup
17
- sleep(0.01)
18
- @pool.reaped.should be_true
19
- end
20
-
21
- it "should sleep after reap!" do
22
- @pool.reaped.should be_false
23
- @pool.lets_reap = true
24
- @reaper.wakeup
25
- sleep(0.01)
26
- @reaper.status.should eql('sleep')
27
- end
28
- end
@@ -1,223 +0,0 @@
1
- require 'spec_helper'
2
- require 'hot_tub/sessions'
3
- require 'uri'
4
- require 'time'
5
- describe HotTub::Sessions do
6
-
7
- context 'initialized without a block' do
8
- it "should raise error if block is not supplied" do
9
- lambda {HotTub::Sessions.new}.should raise_error(ArgumentError)
10
- end
11
- end
12
- context 'initialized with a block' do
13
- before(:each) do
14
- @url = "https://www.somewebsite.com"
15
- @uri = URI(@url)
16
- @sessions = HotTub::Sessions.new { |url| MocClient.new(url) }
17
- end
18
-
19
- describe '#to_url' do
20
- context "passed URL string" do
21
- it "should return key with URI scheme-domain" do
22
- @sessions.send(:to_key,@url).should eql("#{@uri.scheme}://#{@uri.host}:#{@uri.port}")
23
- end
24
- end
25
-
26
- context "passed URI" do
27
- it "should return key with URI scheme-domain" do
28
- @sessions.send(:to_key,@uri).should eql("#{@uri.scheme}://#{@uri.host}:#{@uri.port}")
29
- end
30
- end
31
-
32
- context "invalid argument" do
33
- it "should raise an ArgumentError" do
34
- lambda { @sessions.send(:to_key, nil) }.should raise_error(ArgumentError)
35
- end
36
- it "should raise URI::InvalidURIError with bad url" do
37
- lambda { @sessions.send(:to_key,"bad url") }.should raise_error(URI::InvalidURIError)
38
- end
39
- end
40
- end
41
-
42
- describe '#sessions' do
43
- context 'HotTub::Pool as client' do
44
- it "should add a new client for the url" do
45
- with_pool_options = HotTub::Sessions.new { |url| HotTub::Pool.new(:size => 13) { MocClient.new(url) } }
46
- with_pool_options.sessions(@url)
47
- sessions = with_pool_options.instance_variable_get(:@sessions)
48
- sessions.size.should eql(1)
49
- sessions.each_value {|v| v.should be_a( HotTub::Pool)}
50
- end
51
- end
52
-
53
- context 'other clients' do
54
- it "should add a new client for the url" do
55
- no_pool = HotTub::Sessions.new { |url| Excon.new(url) }
56
- no_pool.sessions(@url)
57
- sessions = no_pool.instance_variable_get(:@sessions)
58
- sessions.size.should eql(1)
59
- sessions.each_value {|v| v.should be_a(Excon::Connection)}
60
- end
61
- end
62
-
63
- context "passed URL string" do
64
- it "should set key with URI scheme-domain" do
65
- @sessions.sessions(@url)
66
- sessions = @sessions.instance_variable_get(:@sessions)
67
- sessions["#{@uri.scheme}://#{@uri.host}:#{@uri.port}"].should be_a(MocClient)
68
- end
69
- end
70
- context "passed URI" do
71
- it "should set key with URI scheme-domain" do
72
- @sessions.sessions(@uri)
73
- sessions = @sessions.instance_variable_get(:@sessions)
74
- sessions["#{@uri.scheme}://#{@uri.host}:#{@uri.port}"].should be_a(MocClient)
75
- end
76
- end
77
-
78
- context "with_pool" do
79
- it "should initialize a new HotTub::Pool" do
80
- session_with_pool = HotTub::Sessions.new({:with_pool => true}) { |url| MocClient.new(url) }
81
- pool = session_with_pool.sessions(@url)
82
- pool.should be_a(HotTub::Pool)
83
- end
84
- end
85
- end
86
-
87
- describe '#run' do
88
- it "should work" do
89
- url = HotTub::Server.url
90
- sessions = HotTub::Sessions.new { |url| Excon.new(url) }
91
- result = nil
92
- sessions.run(url) do |conn|
93
- result = conn.get.status
94
- end
95
- result.should eql(200)
96
- end
97
-
98
- context "with_pool" do
99
- it "should pass run to pool" do
100
- url = HotTub::Server.url
101
- session_with_pool = HotTub::Sessions.new({:with_pool => true}) { |url|
102
- uri = URI.parse(url)
103
- http = Net::HTTP.new(uri.host, uri.port)
104
- http.use_ssl = false
105
- http.start
106
- http
107
- }
108
- result = nil
109
- session_with_pool.run(url) do |conn|
110
- uri = URI.parse(url)
111
- result = conn.get(uri.path).code
112
- end
113
- result.should eql('200')
114
- end
115
- end
116
- end
117
-
118
- describe '#clean!' do
119
- it "should clean all sessions" do
120
- sessions = HotTub::Sessions.new(:clean => lambda { |clnt| clnt.clean}) { |url| MocClient.new(url) }
121
- sessions.sessions('foo')
122
- sessions.sessions('bar')
123
- sessions.clean!
124
- sessions.instance_variable_get(:@sessions).each_pair do |k,v|
125
- v.cleaned?.should be_true
126
- end
127
- end
128
- context "with_pool" do
129
- it "should clean all pools in sessions" do
130
- sessions = HotTub::Sessions.new(:with_pool => true, :clean => lambda { |clnt| clnt.clean}) { |url| MocClient.new(url) }
131
- sessions.sessions('foo')
132
- sessions.sessions('bar')
133
- sessions.clean!
134
- sessions.instance_variable_get(:@sessions).each_pair do |k,v|
135
- v.instance_variable_get(:@pool).each do |c|
136
- c.cleaned?.should be_true
137
- end
138
- end
139
- end
140
- end
141
- end
142
-
143
- describe '#drain!' do
144
- it "should drain all sessions" do
145
- sessions = HotTub::Sessions.new { |url| MocClient.new(url) }
146
- sessions.sessions('foo')
147
- sessions.sessions('bar')
148
- sessions.drain!
149
- sessions.instance_variable_get(:@sessions).empty?.should be_true
150
- end
151
- context "with_pool" do
152
- it "should drain all pools in sessions" do
153
- sessions = HotTub::Sessions.new(:with_pool => true) { |url| MocClient.new(url) }
154
- sessions.sessions('foo')
155
- sessions.sessions('bar')
156
- sessions.drain!
157
- sessions.instance_variable_get(:@sessions).empty?.should be_true
158
- end
159
- end
160
- end
161
-
162
- describe '#reap!' do
163
- it "should clean all sessions" do
164
- sessions = HotTub::Sessions.new(:reap => lambda { |clnt| clnt.reap}) { |url| MocClient.new(url) }
165
- sessions.sessions('foo')
166
- sessions.sessions('bar')
167
- sessions.reap!
168
- sessions.instance_variable_get(:@sessions).each_pair do |k,v|
169
- v.reaped?.should be_true
170
- end
171
- end
172
- context "with_pool" do
173
- it "should clean all pools in sessions" do
174
- sessions = HotTub::Sessions.new(:with_pool => true, :reap => lambda { |clnt| clnt.reap}) { |url| MocClient.new(url) }
175
- sessions.sessions('foo')
176
- sessions.sessions('bar')
177
- sessions.reap!
178
- sessions.instance_variable_get(:@sessions).each_pair do |k,v|
179
- v.instance_variable_get(:@pool).each do |c|
180
- c.reaped?.should be_true
181
- end
182
- end
183
- end
184
- end
185
- end
186
- context 'integration tests' do
187
- context 'threads' do
188
- it "should work" do
189
- url = HotTub::Server.url
190
- url2 = HotTub::Server2.url
191
- session = HotTub::Sessions.new(:with_pool => true) { |url|
192
- uri = URI.parse(url)
193
- http = Net::HTTP.new(uri.host, uri.port)
194
- http.use_ssl = false
195
- http.start
196
- http
197
- }
198
- failed = false
199
- start_time = Time.now
200
- stop_time = nil
201
- threads = []
202
- lambda {
203
- 10.times.each do
204
- threads << Thread.new do
205
- session.run(url) { |clnt| Thread.current[:result] = clnt.get(URI.parse(url).path).code }
206
- session.run(url2) { |clnt| Thread.current[:result] = clnt.get(URI.parse(url).path).code }
207
- end
208
- end
209
- threads.each do |t|
210
- t.join
211
- end
212
- stop_time = Time.now
213
- }.should_not raise_error # make sure we're thread safe
214
- # Some extra checks just to make sure...
215
- results = threads.collect{ |t| t[:result]}
216
- results.length.should eql(10) # make sure all threads are present
217
- results.uniq.should eql([results.first]) # make sure we got the same results
218
- session.instance_variable_get(:@sessions).keys.length.should eql(2) # make sure sessions were created
219
- end
220
- end
221
- end
222
- end
223
- end