connection_pool 2.2.0 → 2.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  class ConnectionPool
2
- VERSION = "2.2.0"
2
+ VERSION = "2.2.5"
3
3
  end
@@ -0,0 +1,57 @@
1
+ class ConnectionPool
2
+ class Wrapper < ::BasicObject
3
+ METHODS = [:with, :pool_shutdown, :wrapped_pool]
4
+
5
+ def initialize(options = {}, &block)
6
+ @pool = options.fetch(:pool) { ::ConnectionPool.new(options, &block) }
7
+ end
8
+
9
+ def wrapped_pool
10
+ @pool
11
+ end
12
+
13
+ def with(&block)
14
+ @pool.with(&block)
15
+ end
16
+
17
+ def pool_shutdown(&block)
18
+ @pool.shutdown(&block)
19
+ end
20
+
21
+ def pool_size
22
+ @pool.size
23
+ end
24
+
25
+ def pool_available
26
+ @pool.available
27
+ end
28
+
29
+ def respond_to?(id, *args)
30
+ METHODS.include?(id) || with { |c| c.respond_to?(id, *args) }
31
+ end
32
+
33
+ # rubocop:disable Style/MethodMissingSuper
34
+ # rubocop:disable Style/MissingRespondToMissing
35
+ if ::RUBY_VERSION >= "3.0.0"
36
+ def method_missing(name, *args, **kwargs, &block)
37
+ with do |connection|
38
+ connection.send(name, *args, **kwargs, &block)
39
+ end
40
+ end
41
+ elsif ::RUBY_VERSION >= "2.7.0"
42
+ ruby2_keywords def method_missing(name, *args, &block)
43
+ with do |connection|
44
+ connection.send(name, *args, &block)
45
+ end
46
+ end
47
+ else
48
+ def method_missing(name, *args, &block)
49
+ with do |connection|
50
+ connection.send(name, *args, &block)
51
+ end
52
+ end
53
+ end
54
+ # rubocop:enable Style/MethodMissingSuper
55
+ # rubocop:enable Style/MissingRespondToMissing
56
+ end
57
+ end
data/test/helper.rb CHANGED
@@ -1,8 +1,8 @@
1
- gem 'minitest'
1
+ gem "minitest"
2
2
 
3
- require 'minitest/pride'
4
- require 'minitest/autorun'
3
+ require "minitest/pride"
4
+ require "minitest/autorun"
5
5
 
6
6
  $VERBOSE = 1
7
7
 
8
- require_relative '../lib/connection_pool'
8
+ require_relative "../lib/connection_pool"
@@ -1,15 +1,22 @@
1
- require_relative 'helper'
1
+ require_relative "helper"
2
2
 
3
3
  class TestConnectionPool < Minitest::Test
4
-
5
4
  class NetworkConnection
5
+ SLEEP_TIME = 0.1
6
+
6
7
  def initialize
7
8
  @x = 0
8
9
  end
9
10
 
10
- def do_something
11
- @x += 1
12
- sleep 0.05
11
+ def do_something(*_args, increment: 1)
12
+ @x += increment
13
+ sleep SLEEP_TIME
14
+ @x
15
+ end
16
+
17
+ def do_something_with_positional_hash(options)
18
+ @x += options[:increment] || 1
19
+ sleep SLEEP_TIME
13
20
  @x
14
21
  end
15
22
 
@@ -19,7 +26,7 @@ class TestConnectionPool < Minitest::Test
19
26
 
20
27
  def do_something_with_block
21
28
  @x += yield
22
- sleep 0.05
29
+ sleep SLEEP_TIME
23
30
  @x
24
31
  end
25
32
 
@@ -41,12 +48,12 @@ class TestConnectionPool < Minitest::Test
41
48
  end
42
49
 
43
50
  def use_pool(pool, size)
44
- Array.new(size) do
51
+ Array.new(size) {
45
52
  Thread.new do
46
- pool.with do sleep end
53
+ pool.with { sleep }
47
54
  end
48
- end.each do |thread|
49
- Thread.pass until thread.status == 'sleep'
55
+ }.each do |thread|
56
+ Thread.pass until thread.status == "sleep"
50
57
  end
51
58
  end
52
59
 
@@ -58,33 +65,38 @@ class TestConnectionPool < Minitest::Test
58
65
  end
59
66
 
60
67
  def test_basic_multithreaded_usage
61
- pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
68
+ pool_size = 5
69
+ pool = ConnectionPool.new(size: pool_size) { NetworkConnection.new }
70
+
71
+ start = Time.new
72
+
73
+ generations = 3
62
74
 
63
- threads = Array.new(15) do
75
+ result = Array.new(pool_size * generations) {
64
76
  Thread.new do
65
77
  pool.with do |net|
66
78
  net.do_something
67
79
  end
68
80
  end
69
- end
81
+ }.map(&:value)
82
+
83
+ finish = Time.new
70
84
 
71
- a = Time.now
72
- result = threads.map(&:value)
73
- b = Time.now
74
- assert_operator((b - a), :>, 0.125)
75
- assert_equal([1,2,3].cycle(5).sort, result.sort)
85
+ assert_equal((1..generations).cycle(pool_size).sort, result.sort)
86
+
87
+ assert_operator(finish - start, :>, generations * NetworkConnection::SLEEP_TIME)
76
88
  end
77
89
 
78
90
  def test_timeout
79
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
80
- thread = Thread.new do
91
+ pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
92
+ thread = Thread.new {
81
93
  pool.with do |net|
82
94
  net.do_something
83
95
  sleep 0.01
84
96
  end
85
- end
97
+ }
86
98
 
87
- Thread.pass while thread.status == 'run'
99
+ Thread.pass while thread.status == "run"
88
100
 
89
101
  assert_raises Timeout::Error do
90
102
  pool.with { |net| net.do_something }
@@ -98,42 +110,58 @@ class TestConnectionPool < Minitest::Test
98
110
  end
99
111
 
100
112
  def test_with
101
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
113
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
102
114
 
103
115
  pool.with do
104
- assert_raises Timeout::Error do
105
- Thread.new { pool.checkout }.join
106
- end
116
+ Thread.new {
117
+ assert_raises Timeout::Error do
118
+ pool.checkout
119
+ end
120
+ }.join
107
121
  end
108
122
 
109
123
  assert Thread.new { pool.checkout }.join
110
124
  end
111
125
 
126
+ def test_then
127
+ pool = ConnectionPool.new { Object.new }
128
+
129
+ assert_equal pool.method(:then), pool.method(:with)
130
+ end
131
+
112
132
  def test_with_timeout
113
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
133
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
114
134
 
115
135
  assert_raises Timeout::Error do
116
136
  Timeout.timeout(0.01) do
117
137
  pool.with do |obj|
118
- assert_equal 0, pool.instance_variable_get(:@available).instance_variable_get(:@que).size
138
+ assert_equal 0, pool.available
119
139
  sleep 0.015
120
140
  end
121
141
  end
122
142
  end
123
- assert_equal 1, pool.instance_variable_get(:@available).instance_variable_get(:@que).size
143
+ assert_equal 1, pool.available
124
144
  end
125
145
 
126
- def test_checkout_ignores_timeout
127
- skip("Thread.handle_interrupt not available") unless Thread.respond_to?(:handle_interrupt)
146
+ def test_invalid_size
147
+ assert_raises ArgumentError, TypeError do
148
+ ConnectionPool.new(timeout: 0, size: nil) { Object.new }
149
+ end
150
+ assert_raises ArgumentError, TypeError do
151
+ ConnectionPool.new(timeout: 0, size: "") { Object.new }
152
+ end
153
+ end
128
154
 
129
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
155
+ def test_handle_interrupt_ensures_checkin
156
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
130
157
  def pool.checkout(options)
131
158
  sleep 0.015
132
159
  super
133
160
  end
134
161
 
135
162
  did_something = false
136
- assert_raises Timeout::Error do
163
+
164
+ action = lambda do
137
165
  Timeout.timeout(0.01) do
138
166
  pool.with do |obj|
139
167
  did_something = true
@@ -145,18 +173,33 @@ class TestConnectionPool < Minitest::Test
145
173
  end
146
174
  end
147
175
  end
148
- assert did_something
149
- assert_equal 1, pool.instance_variable_get(:@available).instance_variable_get(:@que).size
176
+
177
+ if RUBY_ENGINE == "ruby"
178
+ # These asserts rely on the Ruby implementation reaching `did_something =
179
+ # true` before the interrupt is detected by the thread. Interrupt
180
+ # detection timing is implementation-specific in practice, with JRuby,
181
+ # Rubinius, and TruffleRuby all having different interrupt timings to MRI.
182
+ # In fact they generally detect interrupts more quickly than MRI, so they
183
+ # may not reach `did_something = true` before detecting the interrupt.
184
+
185
+ assert_raises Timeout::Error, &action
186
+
187
+ assert did_something
188
+ else
189
+ action.call
190
+ end
191
+
192
+ assert_equal 1, pool.available
150
193
  end
151
194
 
152
195
  def test_explicit_return
153
- pool = ConnectionPool.new(:timeout => 0, :size => 1) do
196
+ pool = ConnectionPool.new(timeout: 0, size: 1) {
154
197
  mock = Minitest::Mock.new
155
198
  def mock.disconnect!
156
199
  raise "should not disconnect upon explicit return"
157
200
  end
158
201
  mock
159
- end
202
+ }
160
203
 
161
204
  pool.with do |conn|
162
205
  return true
@@ -164,33 +207,35 @@ class TestConnectionPool < Minitest::Test
164
207
  end
165
208
 
166
209
  def test_with_timeout_override
167
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
210
+ pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
168
211
 
169
- t = Thread.new do
212
+ t = Thread.new {
170
213
  pool.with do |net|
171
214
  net.do_something
172
215
  sleep 0.01
173
216
  end
174
- end
217
+ }
175
218
 
176
- Thread.pass while t.status == 'run'
219
+ Thread.pass while t.status == "run"
177
220
 
178
221
  assert_raises Timeout::Error do
179
222
  pool.with { |net| net.do_something }
180
223
  end
181
224
 
182
- pool.with(:timeout => 0.1) do |conn|
225
+ pool.with(timeout: 2 * NetworkConnection::SLEEP_TIME) do |conn|
183
226
  refute_nil conn
184
227
  end
185
228
  end
186
229
 
187
230
  def test_checkin
188
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
231
+ pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
189
232
  conn = pool.checkout
190
233
 
191
- assert_raises Timeout::Error do
192
- Thread.new { pool.checkout }.join
193
- end
234
+ Thread.new {
235
+ assert_raises Timeout::Error do
236
+ pool.checkout
237
+ end
238
+ }.join
194
239
 
195
240
  pool.checkin
196
241
 
@@ -198,22 +243,19 @@ class TestConnectionPool < Minitest::Test
198
243
  end
199
244
 
200
245
  def test_returns_value
201
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
202
- assert_equal 1, pool.with {|o| 1 }
246
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
247
+ assert_equal 1, pool.with { |o| 1 }
203
248
  end
204
249
 
205
250
  def test_checkin_never_checkout
206
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
207
-
208
- e = assert_raises ConnectionPool::Error do
209
- pool.checkin
210
- end
251
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
211
252
 
212
- assert_equal 'no connections are checked out', e.message
253
+ e = assert_raises(ConnectionPool::Error) { pool.checkin }
254
+ assert_equal "no connections are checked out", e.message
213
255
  end
214
256
 
215
257
  def test_checkin_no_current_checkout
216
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
258
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
217
259
 
218
260
  pool.checkout
219
261
  pool.checkin
@@ -224,18 +266,18 @@ class TestConnectionPool < Minitest::Test
224
266
  end
225
267
 
226
268
  def test_checkin_twice
227
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { Object.new }
269
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
228
270
 
229
271
  pool.checkout
230
272
  pool.checkout
231
273
 
232
274
  pool.checkin
233
275
 
234
- assert_raises Timeout::Error do
235
- Thread.new do
276
+ Thread.new {
277
+ assert_raises Timeout::Error do
236
278
  pool.checkout
237
- end.join
238
- end
279
+ end
280
+ }.join
239
281
 
240
282
  pool.checkin
241
283
 
@@ -243,7 +285,7 @@ class TestConnectionPool < Minitest::Test
243
285
  end
244
286
 
245
287
  def test_checkout
246
- pool = ConnectionPool.new(:size => 1) { NetworkConnection.new }
288
+ pool = ConnectionPool.new(size: 1) { NetworkConnection.new }
247
289
 
248
290
  conn = pool.checkout
249
291
 
@@ -253,18 +295,18 @@ class TestConnectionPool < Minitest::Test
253
295
  end
254
296
 
255
297
  def test_checkout_multithread
256
- pool = ConnectionPool.new(:size => 2) { NetworkConnection.new }
298
+ pool = ConnectionPool.new(size: 2) { NetworkConnection.new }
257
299
  conn = pool.checkout
258
300
 
259
- t = Thread.new do
301
+ t = Thread.new {
260
302
  pool.checkout
261
- end
303
+ }
262
304
 
263
305
  refute_same conn, t.value
264
306
  end
265
307
 
266
308
  def test_checkout_timeout
267
- pool = ConnectionPool.new(:timeout => 0, :size => 0) { Object.new }
309
+ pool = ConnectionPool.new(timeout: 0, size: 0) { Object.new }
268
310
 
269
311
  assert_raises Timeout::Error do
270
312
  pool.checkout
@@ -272,34 +314,36 @@ class TestConnectionPool < Minitest::Test
272
314
  end
273
315
 
274
316
  def test_checkout_timeout_override
275
- pool = ConnectionPool.new(:timeout => 0, :size => 1) { NetworkConnection.new }
317
+ pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
276
318
 
277
- thread = Thread.new do
319
+ thread = Thread.new {
278
320
  pool.with do |net|
279
321
  net.do_something
280
322
  sleep 0.01
281
323
  end
282
- end
324
+ }
283
325
 
284
- Thread.pass while thread.status == 'run'
326
+ Thread.pass while thread.status == "run"
285
327
 
286
328
  assert_raises Timeout::Error do
287
329
  pool.checkout
288
330
  end
289
331
 
290
- assert pool.checkout :timeout => 0.1
332
+ assert pool.checkout timeout: 2 * NetworkConnection::SLEEP_TIME
291
333
  end
292
334
 
293
335
  def test_passthru
294
- pool = ConnectionPool.wrap(:timeout => 0.1, :size => 1) { NetworkConnection.new }
336
+ pool = ConnectionPool.wrap(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
295
337
  assert_equal 1, pool.do_something
296
338
  assert_equal 2, pool.do_something
297
339
  assert_equal 5, pool.do_something_with_block { 3 }
298
340
  assert_equal 6, pool.with { |net| net.fast }
341
+ assert_equal 8, pool.do_something(increment: 2)
342
+ assert_equal 10, pool.do_something_with_positional_hash({ increment: 2, symbol_key: 3, "string_key" => 4 })
299
343
  end
300
344
 
301
345
  def test_passthru_respond_to
302
- pool = ConnectionPool.wrap(:timeout => 0.1, :size => 1) { NetworkConnection.new }
346
+ pool = ConnectionPool.wrap(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
303
347
  assert pool.respond_to?(:with)
304
348
  assert pool.respond_to?(:do_something)
305
349
  assert pool.respond_to?(:do_magic)
@@ -307,67 +351,67 @@ class TestConnectionPool < Minitest::Test
307
351
  end
308
352
 
309
353
  def test_return_value
310
- pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
311
- result = pool.with do |net|
354
+ pool = ConnectionPool.new(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
355
+ result = pool.with { |net|
312
356
  net.fast
313
- end
357
+ }
314
358
  assert_equal 1, result
315
359
  end
316
360
 
317
361
  def test_heavy_threading
318
- pool = ConnectionPool.new(:timeout => 0.5, :size => 3) { NetworkConnection.new }
362
+ pool = ConnectionPool.new(timeout: 0.5, size: 3) { NetworkConnection.new }
319
363
 
320
- threads = Array.new(20) do
364
+ threads = Array.new(20) {
321
365
  Thread.new do
322
366
  pool.with do |net|
323
367
  sleep 0.01
324
368
  end
325
369
  end
326
- end
370
+ }
327
371
 
328
372
  threads.map { |thread| thread.join }
329
373
  end
330
374
 
331
375
  def test_reuses_objects_when_pool_not_saturated
332
- pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
376
+ pool = ConnectionPool.new(size: 5) { NetworkConnection.new }
333
377
 
334
- ids = 10.times.map do
378
+ ids = 10.times.map {
335
379
  pool.with { |c| c.object_id }
336
- end
380
+ }
337
381
 
338
382
  assert_equal 1, ids.uniq.size
339
383
  end
340
384
 
341
385
  def test_nested_checkout
342
386
  recorder = Recorder.new
343
- pool = ConnectionPool.new(:size => 1) { recorder }
387
+ pool = ConnectionPool.new(size: 1) { recorder }
344
388
  pool.with do |r_outer|
345
- @other = Thread.new do |t|
389
+ @other = Thread.new { |t|
346
390
  pool.with do |r_other|
347
- r_other.do_work('other')
391
+ r_other.do_work("other")
348
392
  end
349
- end
393
+ }
350
394
 
351
395
  pool.with do |r_inner|
352
- r_inner.do_work('inner')
396
+ r_inner.do_work("inner")
353
397
  end
354
398
 
355
399
  Thread.pass
356
400
 
357
- r_outer.do_work('outer')
401
+ r_outer.do_work("outer")
358
402
  end
359
403
 
360
404
  @other.join
361
405
 
362
- assert_equal ['inner', 'outer', 'other'], recorder.calls
406
+ assert_equal ["inner", "outer", "other"], recorder.calls
363
407
  end
364
408
 
365
409
  def test_shutdown_is_executed_for_all_connections
366
410
  recorders = []
367
411
 
368
- pool = ConnectionPool.new(:size => 3) do
412
+ pool = ConnectionPool.new(size: 3) {
369
413
  Recorder.new.tap { |r| recorders << r }
370
- end
414
+ }
371
415
 
372
416
  threads = use_pool pool, 3
373
417
 
@@ -381,9 +425,9 @@ class TestConnectionPool < Minitest::Test
381
425
  end
382
426
 
383
427
  def test_raises_error_after_shutting_down
384
- pool = ConnectionPool.new(:size => 1) { true }
428
+ pool = ConnectionPool.new(size: 1) { true }
385
429
 
386
- pool.shutdown { }
430
+ pool.shutdown {}
387
431
 
388
432
  assert_raises ConnectionPool::PoolShuttingDownError do
389
433
  pool.checkout
@@ -393,9 +437,9 @@ class TestConnectionPool < Minitest::Test
393
437
  def test_runs_shutdown_block_asynchronously_if_connection_was_in_use
394
438
  recorders = []
395
439
 
396
- pool = ConnectionPool.new(:size => 3) do
440
+ pool = ConnectionPool.new(size: 3) {
397
441
  Recorder.new.tap { |r| recorders << r }
398
- end
442
+ }
399
443
 
400
444
  threads = use_pool pool, 2
401
445
 
@@ -415,7 +459,7 @@ class TestConnectionPool < Minitest::Test
415
459
  end
416
460
 
417
461
  def test_raises_an_error_if_shutdown_is_called_without_a_block
418
- pool = ConnectionPool.new(:size => 1) { }
462
+ pool = ConnectionPool.new(size: 1) {}
419
463
 
420
464
  assert_raises ArgumentError do
421
465
  pool.shutdown
@@ -425,9 +469,9 @@ class TestConnectionPool < Minitest::Test
425
469
  def test_shutdown_is_executed_for_all_connections_in_wrapped_pool
426
470
  recorders = []
427
471
 
428
- wrapper = ConnectionPool::Wrapper.new(:size => 3) do
472
+ wrapper = ConnectionPool::Wrapper.new(size: 3) {
429
473
  Recorder.new.tap { |r| recorders << r }
430
- end
474
+ }
431
475
 
432
476
  threads = use_pool wrapper, 3
433
477
 
@@ -440,6 +484,11 @@ class TestConnectionPool < Minitest::Test
440
484
  assert_equal [["shutdown"]] * 3, recorders.map { |r| r.calls }
441
485
  end
442
486
 
487
+ def test_wrapper_wrapped_pool
488
+ wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
489
+ assert_equal ConnectionPool, wrapper.wrapped_pool.class
490
+ end
491
+
443
492
  def test_wrapper_method_missing
444
493
  wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
445
494
 
@@ -456,17 +505,17 @@ class TestConnectionPool < Minitest::Test
456
505
  end
457
506
 
458
507
  def test_wrapper_with
459
- wrapper = ConnectionPool::Wrapper.new(:timeout => 0, :size => 1) { Object.new }
508
+ wrapper = ConnectionPool::Wrapper.new(timeout: 0, size: 1) { Object.new }
460
509
 
461
510
  wrapper.with do
462
- assert_raises Timeout::Error do
463
- Thread.new do
464
- wrapper.with { flunk 'connection checked out :(' }
465
- end.join
466
- end
511
+ Thread.new {
512
+ assert_raises Timeout::Error do
513
+ wrapper.with { flunk "connection checked out :(" }
514
+ end
515
+ }.join
467
516
  end
468
517
 
469
- assert Thread.new { wrapper.with { } }.join
518
+ assert Thread.new { wrapper.with {} }.join
470
519
  end
471
520
 
472
521
  class ConnWithEval
@@ -481,4 +530,38 @@ class TestConnectionPool < Minitest::Test
481
530
  assert_equal "eval'ed 1", wrapper.eval(1)
482
531
  end
483
532
 
533
+ def test_wrapper_with_connection_pool
534
+ recorder = Recorder.new
535
+ pool = ConnectionPool.new(size: 1) { recorder }
536
+ wrapper = ConnectionPool::Wrapper.new(pool: pool)
537
+
538
+ pool.with { |r| r.do_work("with") }
539
+ wrapper.do_work("wrapped")
540
+
541
+ assert_equal ["with", "wrapped"], recorder.calls
542
+ end
543
+
544
+ def test_stats_without_active_connection
545
+ pool = ConnectionPool.new(size: 2) { NetworkConnection.new }
546
+
547
+ assert_equal(2, pool.size)
548
+ assert_equal(2, pool.available)
549
+ end
550
+
551
+ def test_stats_with_active_connection
552
+ pool = ConnectionPool.new(size: 2) { NetworkConnection.new }
553
+
554
+ pool.with do
555
+ assert_equal(1, pool.available)
556
+ end
557
+ end
558
+
559
+ def test_stats_with_string_size
560
+ pool = ConnectionPool.new(size: "2") { NetworkConnection.new }
561
+
562
+ pool.with do
563
+ assert_equal(2, pool.size)
564
+ assert_equal(1, pool.available)
565
+ end
566
+ end
484
567
  end