Skip to content

Commit 48753a3

Browse files
committed
test: add test for check that underlying connection is closed
Closes #31
1 parent 6f785f7 commit 48753a3

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

test/mysql.test.lua

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ local mysql = require('mysql')
77
local json = require('json')
88
local tap = require('tap')
99
local fiber = require('fiber')
10+
local fio = require('fio')
11+
local ffi = require('ffi')
1012

1113
local host, port, user, password, db = string.match(os.getenv('MYSQL') or '',
1214
"([^:]*):([^:]*):([^:]*):([^:]*):([^:]*)")
@@ -481,8 +483,41 @@ local function test_connection_reset(test, pool)
481483
assert(pool.queue:is_full(), 'test case postcondition fails')
482484
end
483485

486+
local function test_underlying_conn_closed_during_gc(test)
487+
test:plan(1)
488+
if jit.os ~= 'Linux' then
489+
test:skip('non-Linux OS')
490+
return
491+
end
492+
-- Basing on the statement, that file descriptors are recycled
493+
-- in ascending order. It means, that if we call open() and
494+
-- immediately close(), we get the first vacant index for a
495+
-- new resource in the file descriptor table. It is important
496+
-- not to call any procedures between open() and close() that
497+
-- may affect the file descriptor table. After that, we
498+
-- immediately create connection, which creates a socket.
499+
-- Socket is a resource, which occupies the first vacant index
500+
-- in the file descriptor table. We check that the socket is
501+
-- indeed destroyed by using fcntl() for this index (handle).
502+
-- See: https://www.win.tue.nl/~aeb/linux/vfs/trail-2.html
503+
local fh, err = fio.open('/dev/zero', {'O_RDONLY'})
504+
if fh == nil then error(err) end
505+
local handle = fh.fh
506+
fh:close()
507+
local conn, err = mysql.connect({ host = host, port = port, user = user,
508+
password = password, db = db })
509+
if conn == nil then error(err) end
510+
511+
-- Somehow we lost the connection handle.
512+
conn = nil
513+
collectgarbage()
514+
ffi.cdef([[ int fcntl(int fd, int cmd, ...); ]])
515+
local F_GETFD = 1
516+
test:ok(ffi.C.fcntl(handle, F_GETFD) == -1, 'descriptor is closed')
517+
end
518+
484519
local test = tap.test('mysql connector')
485-
test:plan(7)
520+
test:plan(8)
486521

487522
test:test('connection old api', test_old_api, conn)
488523
local pool_conn = p:get()
@@ -492,6 +527,8 @@ test:test('concurrent connections', test_conn_concurrent, p)
492527
test:test('int64', test_mysql_int64, p)
493528
test:test('connection pool', test_connection_pool, p)
494529
test:test('connection reset', test_connection_reset, p)
530+
test:test('test_underlying_conn_closed_during_gc',
531+
test_underlying_conn_closed_during_gc, p)
495532
p:close()
496533

497534
os.exit(test:check() and 0 or 1)

0 commit comments

Comments
 (0)