1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
require_relative "spec_helper"
connection_validator_specs = Module.new do
extend Minitest::Spec::DSL
before do
@db = db
@m = Module.new do
def disconnect_connection(conn)
@sqls << 'disconnect'
end
def valid_connection?(conn)
super
conn.valid
end
def connect(server)
conn = super
conn.extend(Module.new do
attr_accessor :valid
end)
conn.valid = true
conn
end
end
@db.extend @m
@db.extension(:connection_validator)
end
it "should still allow new connections" do
@db.synchronize{|c| c}.must_be_kind_of(Sequel::Mock::Connection)
end
it "should only validate if connection idle longer than timeout" do
c1 = @db.synchronize{|c| c}
@db.sqls.must_equal []
@db.synchronize{|c| c}.must_be_same_as(c1)
@db.sqls.must_equal []
@db.pool.connection_validation_timeout = -1
@db.synchronize{|c| c}.must_be_same_as(c1)
@db.sqls.must_equal ['SELECT NULL']
@db.pool.connection_validation_timeout = 1
@db.synchronize{|c| c}.must_be_same_as(c1)
@db.sqls.must_equal []
@db.synchronize{|c| c}.must_be_same_as(c1)
@db.sqls.must_equal []
end
it "should disconnect connection if not valid" do
c1 = @db.synchronize{|c| c}
@db.sqls.must_equal []
c1.valid = false
@db.pool.connection_validation_timeout = -1
c2 = @db.synchronize{|c| c}
@db.sqls.must_equal ['SELECT NULL', 'disconnect']
c2.wont_be_same_as(c1)
end
it "should handle Database#disconnect calls while the connection is checked out" do
@db.synchronize{|c| @db.disconnect}
end
it "should handle disconnected connections" do
proc{@db.synchronize{|c| raise Sequel::DatabaseDisconnectError}}.must_raise Sequel::DatabaseDisconnectError
@db.sqls.must_equal ['disconnect']
end
it "should handle :connection_handling => :disconnect setting" do
@db = Sequel.mock(@db.opts.merge(:connection_handling => :disconnect))
@db.extend @m
@db.extension(:connection_validator)
@db.synchronize{}
@db.sqls.must_equal ['disconnect']
end
it "should disconnect multiple connections repeatedly if they are not valid" do
q, q1 = Queue.new, Queue.new
c1 = nil
c2 = nil
@db.pool.connection_validation_timeout = -1
@db.synchronize do |c|
Thread.new do
@db.synchronize do |cc|
c2 = cc
end
q1.pop
q.push nil
end
q1.push nil
q.pop
c1 = c
end
c1.valid = false
c2.valid = false
c3 = @db.synchronize{|c| c}
@db.sqls.must_equal ['SELECT NULL', 'disconnect', 'SELECT NULL', 'disconnect']
c3.wont_be_same_as(c1)
c3.wont_be_same_as(c2)
end
it "should not leak connection references during disconnect" do
@db.synchronize{}
@db.pool.instance_variable_get(:@connection_timestamps).size.must_equal 1
@db.disconnect
@db.pool.instance_variable_get(:@connection_timestamps).size.must_equal 0
end
it "should not leak connection references" do
c1 = @db.synchronize do |c|
@db.pool.instance_variable_get(:@connection_timestamps).must_equal({})
c
end
@db.pool.instance_variable_get(:@connection_timestamps).must_include(c1)
c1.valid = false
@db.pool.connection_validation_timeout = -1
c2 = @db.synchronize do |c|
@db.pool.instance_variable_get(:@connection_timestamps).must_equal({})
c
end
c2.wont_be_same_as(c1)
@db.pool.instance_variable_get(:@connection_timestamps).wont_include(c1)
@db.pool.instance_variable_get(:@connection_timestamps).must_include(c2)
end
it "should handle case where determining validity requires a connection" do
def @db.valid_connection?(c) synchronize{}; true end
@db.pool.connection_validation_timeout = -1
c1 = @db.synchronize{|c| c}
@db.synchronize{|c| c}.must_be_same_as(c1)
end
end
describe "Sequel::ConnectionValidator with threaded pool" do
def db
Sequel.mock(:test=>false)
end
include connection_validator_specs
end
describe "Sequel::ConnectionValidator with sharded threaded pool" do
def db
Sequel.mock(:test=>false, :servers=>{})
end
include connection_validator_specs
end
|