diff options
Diffstat (limited to 'activerecord/test/cases/connection_pool_test.rb')
-rw-r--r-- | activerecord/test/cases/connection_pool_test.rb | 202 |
1 files changed, 143 insertions, 59 deletions
diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index 8a0f453127..8dc9f761c2 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -3,7 +3,11 @@ require "cases/helper" module ActiveRecord module ConnectionAdapters class ConnectionPoolTest < ActiveRecord::TestCase + attr_reader :pool + def setup + super + # Keep a duplicate pool so we do not bother others @pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec @@ -18,73 +22,161 @@ module ActiveRecord end end - def test_active_connection? - assert !@pool.active_connection? - assert @pool.connection - assert @pool.active_connection? - @pool.release_connection - assert !@pool.active_connection? + def teardown + super + @pool.disconnect! end - def test_pool_caches_columns - columns = @pool.columns['posts'] - assert_equal columns, @pool.columns['posts'] + def active_connections(pool) + pool.connections.find_all(&:in_use?) end - def test_pool_caches_columns_hash - columns_hash = @pool.columns_hash['posts'] - assert_equal columns_hash, @pool.columns_hash['posts'] + def test_checkout_after_close + connection = pool.connection + assert connection.in_use? + + connection.close + assert !connection.in_use? + + assert pool.connection.in_use? end - def test_clearing_column_cache - @pool.columns['posts'] - @pool.columns_hash['posts'] + def test_released_connection_moves_between_threads + thread_conn = nil - @pool.clear_cache! + Thread.new { + pool.with_connection do |conn| + thread_conn = conn + end + }.join - assert_equal 0, @pool.columns.size - assert_equal 0, @pool.columns_hash.size - end + assert thread_conn - def test_primary_key - assert_equal 'id', @pool.primary_keys['posts'] + Thread.new { + pool.with_connection do |conn| + assert_equal thread_conn, conn + end + }.join end - def test_primary_key_for_non_existent_table - assert_equal 'id', @pool.primary_keys['omgponies'] + def test_with_connection + assert_equal 0, active_connections(pool).size + + main_thread = pool.connection + assert_equal 1, active_connections(pool).size + + Thread.new { + pool.with_connection do |conn| + assert conn + assert_equal 2, active_connections(pool).size + end + assert_equal 1, active_connections(pool).size + }.join + + main_thread.close + assert_equal 0, active_connections(pool).size end - def test_primary_key_is_set_on_columns - posts_columns = @pool.columns_hash['posts'] - assert posts_columns['id'].primary + def test_active_connection_in_use + assert !pool.active_connection? + main_thread = pool.connection + + assert pool.active_connection? + + main_thread.close + + assert !pool.active_connection? + end - (posts_columns.keys - ['id']).each do |key| - assert !posts_columns[key].primary + def test_full_pool_exception + assert_raises(PoolFullError) do + (@pool.size + 1).times do + @pool.checkout + end end end - def test_clear_stale_cached_connections! - pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec + def test_full_pool_blocks + cs = @pool.size.times.map { @pool.checkout } + t = Thread.new { @pool.checkout } - threads = [ - Thread.new { pool.connection }, - Thread.new { pool.connection }] + # make sure our thread is in the timeout section + Thread.pass until t.status == "sleep" - threads.map { |t| t.join } + connection = cs.first + connection.close + assert_equal connection, t.join.value + end - pool.extend Module.new { - attr_accessor :checkins - def checkin conn - @checkins << conn - conn.object_id - end - } - pool.checkins = [] + def test_removing_releases_latch + cs = @pool.size.times.map { @pool.checkout } + t = Thread.new { @pool.checkout } + + # make sure our thread is in the timeout section + Thread.pass until t.status == "sleep" + + connection = cs.first + @pool.remove connection + assert_respond_to t.join.value, :execute + end + + def test_reap_and_active + @pool.checkout + @pool.checkout + @pool.checkout + @pool.timeout = 0 + + connections = @pool.connections.dup + + @pool.reap + + assert_equal connections.length, @pool.connections.length + end + + def test_reap_inactive + @pool.checkout + @pool.checkout + @pool.checkout + @pool.timeout = 0 + + connections = @pool.connections.dup + connections.each do |conn| + conn.extend(Module.new { def active?; false; end; }) + end + + @pool.reap + + assert_equal 0, @pool.connections.length + ensure + connections.each(&:close) + end + + def test_remove_connection + conn = @pool.checkout + assert conn.in_use? + + length = @pool.connections.length + @pool.remove conn + assert conn.in_use? + assert_equal(length - 1, @pool.connections.length) + ensure + conn.close + end + + def test_remove_connection_for_thread + conn = @pool.connection + @pool.remove conn + assert_not_equal(conn, @pool.connection) + ensure + conn.close if conn + end - cleared_threads = pool.clear_stale_cached_connections! - assert((cleared_threads - threads.map { |x| x.object_id }).empty?, - "threads should have been removed") - assert_equal pool.checkins.length, threads.length + def test_active_connection? + assert !@pool.active_connection? + assert @pool.connection + assert @pool.active_connection? + @pool.release_connection + assert !@pool.active_connection? end def test_checkout_behaviour @@ -96,24 +188,16 @@ module ActiveRecord threads << Thread.new(i) do |pool_count| connection = pool.connection assert_not_nil connection + connection.close end end - threads.each {|t| t.join} + threads.each(&:join) Thread.new do - threads.each do |t| - thread_ids = pool.instance_variable_get(:@reserved_connections).keys - assert thread_ids.include?(t.object_id) - end - - pool.connection - threads.each do |t| - thread_ids = pool.instance_variable_get(:@reserved_connections).keys - assert !thread_ids.include?(t.object_id) - end - end.join() - + assert pool.connection + pool.connection.close + end.join end def test_automatic_reconnect= |