hot_tub 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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