From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng2.m.smailru.net (smtpng2.m.smailru.net [94.100.179.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id AA58C46971A for ; Fri, 6 Dec 2019 18:44:20 +0300 (MSK) From: Ilya Kosarev Date: Fri, 6 Dec 2019 18:44:17 +0300 Message-Id: <20191206154417.5213-1-i.kosarev@tarantool.org> Subject: [Tarantool-patches] [PATCH v2] test: fix flaky socket test List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org socket.test had a number of flaky problems: - socket readiness expectation - race conditions on socket shutdown in emulation test cases - tcp_server stability in socket receive inconsistent behavior case Now they are solved. Port randomization is improved. Socket test is not fragile anymore. Closes #4451, #4426, #4469 --- Branch: https://github.com/tarantool/tarantool/tree/i.kosarev/gh-4426-4451-fix-socket-test Issues: https://github.com/tarantool/tarantool/issues/4426 https://github.com/tarantool/tarantool/issues/4451 https://github.com/tarantool/tarantool/issues/4469 Changes in v2: - reconsider socket readiness expectation - reduced conditions waiting time test/app/socket.result | 80 +++++++++++++++++++++++++--------------- test/app/socket.test.lua | 56 +++++++++++++++++++--------- test/app/suite.ini | 1 - 3 files changed, 90 insertions(+), 47 deletions(-) diff --git a/test/app/socket.result b/test/app/socket.result index fd299424c96..0095b89b867 100644 --- a/test/app/socket.result +++ b/test/app/socket.result @@ -45,6 +45,9 @@ test_run:cmd("push filter '(error: .builtin/.*[.]lua):[0-9]+' to '\\1'") WAIT_COND_TIME = 10 --- ... +WAIT_TCP_CONNECT_TIME = 240 +--- +... socket('PF_INET', 'SOCK_STREAM', 'tcp121222'); --- - null @@ -107,7 +110,7 @@ s:nonblock(true) --- - true ... -s:readable(.1) +s:readable(WAIT_TCP_CONNECT_TIME) --- - true ... @@ -308,7 +311,7 @@ sc:nonblock(true) --- - true ... -sc:readable(.5) +sc:readable(WAIT_TCP_CONNECT_TIME) --- - true ... @@ -451,7 +454,7 @@ sc:sysconnect('127.0.0.1', s:name().port) or errno() == errno.EINPROGRESS --- - true ... -sc:writable(10) +sc:writable(WAIT_TCP_CONNECT_TIME) --- - true ... @@ -754,7 +757,7 @@ string.match(tostring(sc), ', peer') == nil --- - true ... -sc:writable() +sc:writable(WAIT_TCP_CONNECT_TIME) --- - true ... @@ -1074,6 +1077,15 @@ master:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true) --- - true ... +seed = '' +--- +... +for d in string.gmatch(box.info.uuid, '%d') do seed = seed .. d end +--- +... +math.randomseed(tonumber(seed)) +--- +... port = 32768 + math.random(0, 32767) --- ... @@ -1822,8 +1834,14 @@ test_run:cmd("setopt delimiter ';'") --- - true ... +socket_opened = true cfiber = fiber.create(function(sc, rch, wch) - while sc:send(wch:get()) and rch:put(sc:receive("*l")) do end + while socket_opened do + sc:send(wch:get()) + local data = sc:receive("*l") + if not socket_opened then sc:close() end + rch:put(data) + end end, sc, rch, wch); --- ... @@ -1936,6 +1954,9 @@ c:receive("*l") --- - ... +socket_opened = false +--- +... wch:put("Fu") --- - true @@ -1944,10 +1965,6 @@ c:send("354 Please type your message\n") --- - 29 ... -sc:close() ---- -- 1 -... c:receive("*l", "Line: ") --- - null @@ -2816,7 +2833,7 @@ test_run:cmd("clear filter") --- - true ... --- case: sicket receive inconsistent behavior +-- case: socket receive inconsistent behavior chan = fiber.channel() --- ... @@ -2826,41 +2843,46 @@ counter = 0 fn = function(s) counter = 0; while true do s:write((tostring(counter)):rep(chan:get())); counter = counter + 1 end end --- ... -srv = socket.tcp_server('0.0.0.0', 8888, fn) +srv = nil --- ... -s = socket.connect('localhost', 8888) +test_run:cmd("setopt delimiter ';'") --- +- true ... -chan:put(5) +test_run:wait_cond(function() + port = 32768 + math.random(0, 32767) + srv = socket.tcp_server('0.0.0.0', port, fn) + return srv ~= nil +end, WAIT_COND_TIME); --- - true ... -chan:put(5) +receive1 = nil; receive2 = nil; --- -- true ... -s:receive(5) +if srv ~= nil then + s = socket.connect('localhost', port) + chan:put(5) + chan:put(5) + receive1 = s:receive(5) + chan:put(5) + s:settimeout(1) + receive2 = s:receive('*a') + s:close() + srv:close() +end; --- -- '00000' ... -chan:put(5) +test_run:cmd("setopt delimiter ''"); --- - true ... -s:settimeout(1) +receive1 --- -- 1 +- '00000' ... -s:receive('*a') +receive2 --- - '1111122222' ... -s:close() ---- -- 1 -... -srv:close() ---- -- true -... diff --git a/test/app/socket.test.lua b/test/app/socket.test.lua index c72d41763f4..be375a4215a 100644 --- a/test/app/socket.test.lua +++ b/test/app/socket.test.lua @@ -14,6 +14,7 @@ test_run = env.new() test_run:cmd("push filter '(error: .builtin/.*[.]lua):[0-9]+' to '\\1'") WAIT_COND_TIME = 10 +WAIT_TCP_CONNECT_TIME = 240 socket('PF_INET', 'SOCK_STREAM', 'tcp121222'); @@ -39,7 +40,7 @@ s:nonblock(false) s:nonblock() s:nonblock(true) -s:readable(.1) +s:readable(WAIT_TCP_CONNECT_TIME) s:wait(.1) socket.iowait(s:fd(), 'RW') socket.iowait(s:fd(), 3) @@ -100,7 +101,7 @@ sc = socket('PF_INET', 'SOCK_STREAM', 'tcp') sc:nonblock(false) sc:sysconnect('127.0.0.1', s:name().port) sc:nonblock(true) -sc:readable(.5) +sc:readable(WAIT_TCP_CONNECT_TIME) sc:sysread() string.match(tostring(sc), ', peer') ~= nil #sevres @@ -140,7 +141,7 @@ s:listen(128) sc = socket('PF_INET', 'SOCK_STREAM', 'tcp') sc:sysconnect('127.0.0.1', s:name().port) or errno() == errno.EINPROGRESS -sc:writable(10) +sc:writable(WAIT_TCP_CONNECT_TIME) sc:write('Hello, world') sa, addr = s:accept() @@ -243,7 +244,7 @@ sc:getsockopt('SOL_SOCKET', 'SO_ERROR') sc:nonblock(true) sc:sysconnect('127.0.0.1', 3458) or errno() == errno.EINPROGRESS or errno() == errno.ECONNREFUSED string.match(tostring(sc), ', peer') == nil -sc:writable() +sc:writable(WAIT_TCP_CONNECT_TIME) string.match(tostring(sc), ', peer') == nil socket_error = sc:getsockopt('SOL_SOCKET', 'SO_ERROR') socket_error == errno.ECONNREFUSED or socket_error == 0 @@ -343,6 +344,9 @@ s = nil -- random port master = socket('PF_INET', 'SOCK_STREAM', 'tcp') master:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true) +seed = '' +for d in string.gmatch(box.info.uuid, '%d') do seed = seed .. d end +math.randomseed(tonumber(seed)) port = 32768 + math.random(0, 32767) -- SO_REUSEADDR allows to bind to the same source addr:port twice, -- so listen() can return EADDRINUSE and so we check it within @@ -619,8 +623,14 @@ s:settimeout(100500) rch, wch = fiber.channel(1), fiber.channel(1) sc = socket.connect(host, port) test_run:cmd("setopt delimiter ';'") +socket_opened = true cfiber = fiber.create(function(sc, rch, wch) - while sc:send(wch:get()) and rch:put(sc:receive("*l")) do end + while socket_opened do + sc:send(wch:get()) + local data = sc:receive("*l") + if not socket_opened then sc:close() end + rch:put(data) + end end, sc, rch, wch); test_run:cmd("setopt delimiter ''"); @@ -651,9 +661,9 @@ rch:get() wch:put("DATA\n") c:receive(4) c:receive("*l") +socket_opened = false wch:put("Fu") c:send("354 Please type your message\n") -sc:close() c:receive("*l", "Line: ") c:receive() c:receive(10) @@ -960,18 +970,30 @@ server:close() test_run:cmd("clear filter") --- case: sicket receive inconsistent behavior +-- case: socket receive inconsistent behavior chan = fiber.channel() counter = 0 fn = function(s) counter = 0; while true do s:write((tostring(counter)):rep(chan:get())); counter = counter + 1 end end -srv = socket.tcp_server('0.0.0.0', 8888, fn) -s = socket.connect('localhost', 8888) -chan:put(5) -chan:put(5) -s:receive(5) -chan:put(5) -s:settimeout(1) -s:receive('*a') -s:close() -srv:close() +srv = nil +test_run:cmd("setopt delimiter ';'") +test_run:wait_cond(function() + port = 32768 + math.random(0, 32767) + srv = socket.tcp_server('0.0.0.0', port, fn) + return srv ~= nil +end, WAIT_COND_TIME); +receive1 = nil; receive2 = nil; +if srv ~= nil then + s = socket.connect('localhost', port) + chan:put(5) + chan:put(5) + receive1 = s:receive(5) + chan:put(5) + s:settimeout(1) + receive2 = s:receive('*a') + s:close() + srv:close() +end; +test_run:cmd("setopt delimiter ''"); +receive1 +receive2 diff --git a/test/app/suite.ini b/test/app/suite.ini index 79432e29a76..dd802d98cf9 100644 --- a/test/app/suite.ini +++ b/test/app/suite.ini @@ -7,4 +7,3 @@ use_unix_sockets = True use_unix_sockets_iproto = True is_parallel = True pretest_clean = True -fragile = socket.test.lua ; gh-4426 gh-4451 -- 2.17.1