Just observed that my test cases for broken connections actually act on healthy connections. I mean the following cases:
|
-- Case: the same, but for broken connection. |
|
test:test('loss a broken connection', function(test) |
|
test:plan(2) |
|
|
|
assert(pool.size >= 1, 'test case precondition fails') |
|
|
|
-- Get a connection, make a bad query and loss the |
|
-- connection. |
|
local conn = pool:get() |
|
local ok = pcall(conn.execute, conn, 'bad query') |
|
test:ok(not ok, 'a query actually fails') |
|
conn = nil -- luacheck: no unused |
|
|
|
-- Collect the lost connection. |
|
collectgarbage('collect') |
|
|
|
-- Verify that a pool is aware of collected connections. |
|
test:is(pool.queue:count(), pool.size, 'all connections are put back') |
|
end) |
|
-- Case: get a connection, broke it and put back. |
|
test:test('get, broke and put a connection', function(test) |
|
test:plan(2) |
|
|
|
assert(pool.size >= 1, 'test case precondition fails') |
|
|
|
-- Get a connection and make a bad query. |
|
local conn = pool:get() |
|
local ok = pcall(conn.execute, conn, 'bad query') |
|
test:ok(not ok, 'a query actually fails') |
|
|
|
-- Put the connection back and verify that the pool is full. |
|
pool:put(conn) |
|
test:ok(pool.queue:is_full(), 'a broken connection was given back') |
|
end) |
|
|
|
-- Case: the same, but loss and collect a connection after |
|
-- put. |
|
test:test('get, broke, put and loss a connection', function(test) |
|
test:plan(3) |
|
|
|
assert(pool.size >= 1, 'test case precondition fails') |
|
|
|
-- Get a connection and make a bad query. |
|
local conn = pool:get() |
|
local ok = pcall(conn.execute, conn, 'bad query') |
|
test:ok(not ok, 'a query actually fails') |
|
|
|
-- Put the connection back, loss it and trigger GC. |
|
pool:put(conn) |
|
conn = nil -- luacheck: no unused |
|
collectgarbage('collect') |
|
|
|
-- Verify that the pool is full |
|
test:ok(pool.queue:is_full(), 'a broken connection was given back') |
|
|
|
-- Verify the pool will not be populated by a connection's |
|
-- GC callback. Otherwise :put() will hang. |
|
local item = pool.queue:get() |
|
pool.queue:put(item) |
|
test:ok(true, 'GC callback does not put back a connection that was ' .. |
|
'put manually') |
|
end) |
My initial assumption was that any SQL error (including syntax error) will lead to marking the connection as broken, however it is not so. Only CR_SERVER_LOST or CR_SERVER_GONE_ERROR errors matter here:
|
int err = mysql_errno(raw_conn); |
|
switch (err) { |
|
case CR_SERVER_LOST: |
|
case CR_SERVER_GONE_ERROR: |
|
lua_pushnumber(L, -1); |
|
break; |
|
default: |
|
lua_pushnumber(L, 1); |
|
} |
|
if status ~= 0 then |
|
self.queue:put(status > 0) |
|
return error(datas) |
|
end |
It seems we should find a way to broke a connection from a test. It seems that support of an error injection is needed for Debug build.
Just observed that my test cases for broken connections actually act on healthy connections. I mean the following cases:
mysql/test/mysql.test.lua
Lines 96 to 114 in 2d22046
mysql/test/mysql.test.lua
Lines 312 to 354 in 2d22046
My initial assumption was that any SQL error (including syntax error) will lead to marking the connection as broken, however it is not so. Only CR_SERVER_LOST or CR_SERVER_GONE_ERROR errors matter here:
mysql/mysql/driver.c
Lines 149 to 157 in 2d22046
mysql/mysql/init.lua
Lines 71 to 74 in 2d22046
It seems we should find a way to broke a connection from a test. It seems that support of an error injection is needed for Debug build.