aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/connection_pool_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases/connection_pool_test.rb')
-rw-r--r--activerecord/test/cases/connection_pool_test.rb202
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=