1
0
Fork 0
mirror of https://github.com/mperham/connection_pool synced 2023-03-27 23:22:21 -04:00
connection_pool/test/test_connection_pool.rb
Damian Janowski 5053b327f1 Checking in pushes objects to the head of the queue.
This means that, when not saturated, objects in the pool will be reused
more often.

This behavior allows you to create a pool of objects which in turn have
some kind of time outs themselves. For instance, objects which keep an
underlying TCP connection open until they're idle for some time. An
example of this is `Net::HTTP::Persistent`.

See also issue #20.
2012-12-18 14:05:13 -03:00

150 lines
3.1 KiB
Ruby

Thread.abort_on_exception = true
require 'helper'
class TestConnectionPool < MiniTest::Unit::TestCase
class NetworkConnection
def initialize
@x = 0
end
def do_something
@x += 1
sleep 0.05
@x
end
def fast
@x += 1
end
def do_something_with_block
@x += yield
sleep 0.05
@x
end
def respond_to?(method_id, *args)
method_id == :do_magic || super(method_id, *args)
end
end
def test_basic_multithreaded_usage
pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
threads = []
15.times do
threads << Thread.new do
pool.with_connection do |net|
net.do_something
end
end
end
a = Time.now
result = threads.map(&:value)
b = Time.now
assert_operator((b - a), :>, 0.125)
assert_equal([1,2,3].cycle(5).sort, result.sort)
end
def test_timeout
pool = ConnectionPool.new(:timeout => 0.05, :size => 1) { NetworkConnection.new }
Thread.new do
pool.with do |net|
net.do_something
sleep 0.1
end
end
sleep 0.05
assert_raises Timeout::Error do
pool.with { |net| net.do_something }
end
sleep 0.05
pool.with do |conn|
refute_nil conn
end
end
def test_passthru
pool = ConnectionPool.wrap(:timeout => 0.1, :size => 1) { NetworkConnection.new }
assert_equal 1, pool.do_something
assert_equal 2, pool.do_something
assert_equal 5, pool.do_something_with_block { 3 }
assert_equal 6, pool.with { |net| net.fast }
end
def test_passthru_respond_to
pool = ConnectionPool.wrap(:timeout => 0.1, :size => 1) { NetworkConnection.new }
assert pool.respond_to?(:with)
assert pool.respond_to?(:do_something)
assert pool.respond_to?(:do_magic)
refute pool.respond_to?(:do_lots_of_magic)
end
def test_return_value
pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
result = pool.with_connection do |net|
net.fast
end
assert_equal 1, result
end
def test_heavy_threading
pool = ConnectionPool.new(:timeout => 0.5, :size => 3) { NetworkConnection.new }
20.times do
Thread.new do
pool.with do |net|
sleep 0.05
end
end
end
sleep 0.5
end
def test_reuses_objects_when_pool_not_saturated
pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
ids = 10.times.map do
pool.with { |c| c.object_id }
end
assert_equal 1, ids.uniq.size
end
class Recorder
def initialize
@calls = []
end
attr_reader :calls
def do_work(label)
@calls << label
end
end
def test_nested_checkout
recorder = Recorder.new
pool = ConnectionPool.new(:size => 1) { recorder }
pool.with do |r_outer|
@other = Thread.new do |t|
pool.with do |r_other|
r_other.do_work('other')
end
end
pool.with do |r_inner|
r_inner.do_work('inner')
end
sleep 0.1
r_outer.do_work('outer')
end
@other.join
assert_equal ['inner', 'outer', 'other'], recorder.calls
end
end