Skip to content

test: fix tests on broken connections #37

Open
@Totktonada

Description

@Totktonada

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

-- 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)

mysql/test/mysql.test.lua

Lines 312 to 354 in 2d22046

-- 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:

mysql/mysql/driver.c

Lines 149 to 157 in 2d22046

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);
}

mysql/mysql/init.lua

Lines 71 to 74 in 2d22046

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    code healthImprove code readability, simplify maintenance and so ongood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions