<HTML><BODY>Hi!<br><br>Thanks for your review.<br><pre style="white-space: pre-wrap;" data-mce-style="white-space: pre-wrap;">3 answers are below.</pre><p>Sent v4 including all proposed changes with minor fixes.<br>There are 2 comments in that section.</p><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">
        Вторник, 17 декабря 2019, 3:03 +03:00 от Vladislav Shpilevoy <v.shpilevoy@tarantool.org>:<br><br><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15765410101821021160_BODY">Thanks for the patch!<br><br>
See 6 comments below, and 2 review fix commits in the<br>
end.<br><br>
On 10/12/2019 15:36, Ilya Kosarev wrote:<br>
> test: fix flaky socket test<br>
    
1. You've duplicated the commit title in the<br>
commit message.<br><br>
> <br>
> socket.test had a number of flaky problems:<br>
> - socket readiness expectation<br>
> - race conditions on socket shutdown in emulation test cases<br>
> - tcp_server stability in socket receive inconsistent behavior case<br>
> Now they are solved. Port randomization is improved.<br>
> Socket test is not fragile anymore.<br><br>
2. It depends on definition of 'fragile test'. Any test using UDP<br>
can fail under sufficiently high load. And this test is not an<br>
exception. After your and my fixes it fails extremely rare, but<br>
still fails. That happens under huge load when the kernel starts<br>
dropping UDP packets. Not delivers them with a delay, but drops.<br><br>
But I guess yeah, we can remove the 'fragile' flag. Unless our<br>
test suite will ever try to run 64 socket tests in parallel a<br>
couple of times.<br><br>
> <br>
> Closes #4451, #4426, #4469<br>
> ---<br>
> Branch: <a href="https://github.com/tarantool/tarantool/tree/i.kosarev/gh-4426-4451-fix-socket-test" target="_blank">https://github.com/tarantool/tarantool/tree/i.kosarev/gh-4426-4451-fix-socket-test</a><br>
> Issues: <a href="https://github.com/tarantool/tarantool/issues/4426" target="_blank">https://github.com/tarantool/tarantool/issues/4426</a><br>
>         <a href="https://github.com/tarantool/tarantool/issues/4451" target="_blank">https://github.com/tarantool/tarantool/issues/4451</a><br>
>         <a href="https://github.com/tarantool/tarantool/issues/4469" target="_blank">https://github.com/tarantool/tarantool/issues/4469</a><br>
> <br>
> Changes in v2:<br>
> - reconsidered socket readiness expectation<br>
> - reduced conditions waiting time<br>
> <br>
> Changes in v3:<br>
> - reconsidered expectations to unify them<br>
> - simplified randomization<br>
> <br>
>  test/app/socket.result   | 159 +++++++++++++++++++++++++--------------<br>
>  test/app/socket.test.lua | 123 +++++++++++++++++++-----------<br>
>  test/app/suite.ini       |   1 -<br>
>  3 files changed, 178 insertions(+), 105 deletions(-)<br>
> <br>
> diff --git a/test/app/socket.result b/test/app/socket.result<br>
> index fd299424c96..25ad9034374 100644<br>
> --- a/test/app/socket.result<br>
> +++ b/test/app/socket.result<br>
> @@ -278,14 +278,14 @@ s:error()<br>
>  ---<br>
>  - null<br>
>  ...<br>
> -s:listen(128)<br>
> +s:listen(WAIT_COND_TIME)<br><br>
3. I suggest you to read socket.lua source code. Listen takes<br>
backlog size, not a timeout. The same comment to many other<br>
places.</div></div></div></div></blockquote>3. Right. My bad.<br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15765410101821021160_BODY"><br><br>
>  ---<br>
>  - true<br>
>  ...<br>
>  sevres = {}<br>
>  ---<br>
>  ...<br>
> -type(require('fiber').create(function() s:readable() do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end))<br>
> +type(require('fiber').create(function() s:readable(WAIT_COND_TIME) do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end))<br><br>
4. :readable() has infinity timeout. When you made it WAIT_COND_TIME,<br>
you certainly didn't improve the test stability. The same in other<br>
similar places.</div></div></div></div></blockquote>4. Ok, i see, we don't need to touch infinite timeout cases.<br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15765410101821021160_BODY"><br><br>
>  ---<br>
>  - userdata<br>
>  ...<br>
> @@ -1004,7 +1004,7 @@ socket.tcp_connect('unix/', path), errno() == errno.ECONNREFUSED<br>
>  - null<br>
>  - true<br>
>  ...<br>
> -s:listen()<br>
> +s:listen(WAIT_COND_TIME)<br>
>  ---<br>
>  - true<br>
>  ...<br>
> @@ -1074,6 +1074,9 @@ master:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)<br>
>  ---<br>
>  - true<br>
>  ...<br>
> +math.randomseed(fiber.time())<br><br>
5. This line becomes useless when you've increased the timeout.<br>
Moreover, the random port search below also does not make any<br>
sense. You could use port 0 to bind to any free port instead of<br>
manual guessing for the kernel.</div></div></div></div></blockquote>5. Nice, i didn't consider this possibility. Therefore we don't<br>need to perform manual random port search.<br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15765410101821021160_BODY"><br><br>
> +---<br>
> +...<br>
>  port = 32768 + math.random(0, 32767)<br>
>  ---<br>
>  ...<br>
> @@ -2231,7 +2239,17 @@ test_run:cmd("setopt delimiter ''");<br>
>  receiving_socket = socket('AF_INET', 'SOCK_DGRAM', 'udp')<br>
>  ---<br>
>  ...<br>
> -receiving_socket:bind('127.0.0.1', 0)<br>
> +test_run:cmd("setopt delimiter ';'")<br>
> +---<br>
> +- true<br>
> +...<br>
> +test_run:wait_cond(function()<br>
> +    return receiving_socket:bind('127.0.0.1', 32768 + math.random(0, 32767))<br>
> +end, WAIT_COND_TIME);<br><br>
6. Why? Bind with 0 port finds a suitable port. You don't<br>
need to do random guessing. The same in many other places.<br><br>
> +---<br>
> +- true<br>
> +...<br>
> +test_run:cmd("setopt delimiter ''");<br>
>  ---<br>
>  - true<br>
>  ...<br>
Below are 2 my commits. First with review fixes to the patch. Second<br>
with stabilization of UDP tests (well, not 100% stability, but much<br>
better. 100% would require to rework the tests too much loosing their<br>
purpose).<br><br>
Please, review them, squahs if you agree, and send to a second review<br>
to someone. For example to Alexander. But taking into account urgency<br>
of 2.3.1 maybe we can't wait several weeks more, so ask Kirill.<br><br>
===========================================================================<br><br>
commit fc11ffbd9135554b2b91728483189ababa86c36e<br>
Author: Vladislav Shpilevoy <<a href="mailto:v.shpilevoy@tarantool.org">v.shpilevoy@tarantool.org</a>><br>
Date:   Mon Dec 16 23:33:21 2019 +0100<br><br>
    Review fixes<br><br>
diff --git a/test/app/socket.result b/test/app/socket.result<br>
index 25ad90343..563519315 100644<br>
--- a/test/app/socket.result<br>
+++ b/test/app/socket.result<br>
@@ -278,14 +278,14 @@ s:error()<br>
 ---<br>
 - null<br>
 ...<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(128)<br>
 ---<br>
 - true<br>
 ...<br>
 sevres = {}<br>
 ---<br>
 ...<br>
-type(require('fiber').create(function() s:readable(WAIT_COND_TIME) do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end))<br>
+type(require('fiber').create(function() s:readable() do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end))<br>
 ---<br>
 - userdata<br>
 ...<br>
@@ -440,7 +440,7 @@ s:bind('127.0.0.1', 0)<br>
 ---<br>
 - true<br>
 ...<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(128)<br>
 ---<br>
 - true<br>
 ...<br>
@@ -485,7 +485,7 @@ sa:read(3)<br>
 ---<br>
 - orl<br>
 ...<br>
-sc:writable(WAIT_COND_TIME)<br>
+sc:writable()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -513,7 +513,7 @@ sa:read(1, .01)<br>
 ---<br>
 - null<br>
 ...<br>
-sc:writable(WAIT_COND_TIME)<br>
+sc:writable()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -546,7 +546,7 @@ sc:send('Hello')<br>
 ---<br>
 - 5<br>
 ...<br>
-sa:readable(WAIT_COND_TIME)<br>
+sa:readable()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -646,7 +646,7 @@ sc ~= nil<br>
 ---<br>
 - true<br>
 ...<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(1234)<br>
 ---<br>
 - true<br>
 ...<br>
@@ -665,7 +665,7 @@ sc:error()<br>
 ---<br>
 - null<br>
 ...<br>
-s:readable(WAIT_COND_TIME)<br>
+s:readable()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -754,7 +754,7 @@ string.match(tostring(sc), ', peer') == nil<br>
 ---<br>
 - true<br>
 ...<br>
-sc:writable(WAIT_COND_TIME)<br>
+sc:writable()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -957,7 +957,7 @@ s:bind('127.0.0.1', 0)<br>
 port = s:name().port<br>
 ---<br>
 ...<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -1004,7 +1004,7 @@ socket.tcp_connect('unix/', path), errno() == errno.ECONNREFUSED<br>
 - null<br>
 - true<br>
 ...<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -1070,39 +1070,21 @@ s = nil<br>
 master = socket('PF_INET', 'SOCK_STREAM', 'tcp')<br>
 ---<br>
 ...<br>
-master:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)<br>
+master:bind('127.0.0.1', 0)<br>
 ---<br>
 - true<br>
 ...<br>
-math.randomseed(fiber.time())<br>
----<br>
-...<br>
-port = 32768 + math.random(0, 32767)<br>
+port = master:name().port<br>
 ---<br>
 ...<br>
--- SO_REUSEADDR allows to bind to the same source addr:port twice,<br>
--- so listen() can return EADDRINUSE and so we check it within<br>
--- wait_cond().<br>
 test_run:cmd("setopt delimiter ';'")<br>
 ---<br>
 - true<br>
 ...<br>
-test_run:wait_cond(function()<br>
-    local ok = master:bind('127.0.0.1', port)<br>
-    local ok = ok and master:listen(WAIT_COND_TIME)<br>
-    if not ok then<br>
-        port = 32768 + math.random(32768)<br>
-        return false, master:error()<br>
-    end<br>
-    return true<br>
-end, WAIT_COND_TIME);<br>
----<br>
-- true<br>
-...<br>
 function gh361()<br>
     local s = socket('PF_INET', 'SOCK_STREAM', 'tcp')<br>
     s:sysconnect('127.0.0.1', port)<br>
-    s:wait(WAIT_COND_TIME)<br>
+    s:wait()<br>
     res = s:read(1200)<br>
 end;<br>
 ---<br>
@@ -1149,7 +1131,7 @@ s:error()<br>
 ---<br>
 - null<br>
 ...<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(128)<br>
 ---<br>
 - true<br>
 ...<br>
@@ -1159,7 +1141,7 @@ test_run:cmd("setopt delimiter ';'")<br>
 ...<br>
 f = fiber.create(function()<br>
     for i=1,2 do<br>
-        s:readable(WAIT_COND_TIME)<br>
+        s:readable()<br>
         local sc = s:accept()<br>
         sc:write('ok!')<br>
         sc:shutdown()<br>
@@ -1535,7 +1517,7 @@ s:bind('unix/', path)<br>
 ---<br>
 - true<br>
 ...<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -1762,7 +1744,7 @@ s:bind('127.0.0.1', 0) -- error handling<br>
 - null<br>
 - Invalid argument<br>
 ...<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(10)<br>
 ---<br>
 - 1<br>
 ...<br>
@@ -2239,17 +2221,7 @@ test_run:cmd("setopt delimiter ''");<br>
 receiving_socket = socket('AF_INET', 'SOCK_DGRAM', 'udp')<br>
 ---<br>
 ...<br>
-test_run:cmd("setopt delimiter ';'")<br>
----<br>
-- true<br>
-...<br>
-test_run:wait_cond(function()<br>
-    return receiving_socket:bind('127.0.0.1', 32768 + math.random(0, 32767))<br>
-end, WAIT_COND_TIME);<br>
----<br>
-- true<br>
-...<br>
-test_run:cmd("setopt delimiter ''");<br>
+receiving_socket:bind('127.0.0.1', 0)<br>
 ---<br>
 - true<br>
 ...<br>
@@ -2643,21 +2615,11 @@ listening_socket:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)<br>
 ---<br>
 - true<br>
 ...<br>
-test_run:cmd("setopt delimiter ';'")<br>
----<br>
-- true<br>
-...<br>
-test_run:wait_cond(function()<br>
-    return listening_socket:bind('127.0.0.1', 32768 + math.random(0, 32767))<br>
-end, WAIT_COND_TIME);<br>
----<br>
-- true<br>
-...<br>
-test_run:cmd("setopt delimiter ''");<br>
+listening_socket:bind('127.0.0.1', 0)<br>
 ---<br>
 - true<br>
 ...<br>
-listening_socket:listen(WAIT_COND_TIME)<br>
+listening_socket:listen()<br>
 ---<br>
 - true<br>
 ...<br>
@@ -2671,18 +2633,12 @@ sending_socket:sysconnect('127.0.0.1', listening_socket_port) or errno() == errn<br>
 ---<br>
 - true<br>
 ...<br>
-test_run:cmd("setopt delimiter ';'")<br>
+listening_socket:readable(WAIT_COND_TIME)<br>
 ---<br>
 - true<br>
 ...<br>
-receiving_socket = test_run:wait_cond(function()<br>
-    return listening_socket:accept()<br>
-end, WAIT_COND_TIME);<br>
----<br>
-...<br>
-test_run:cmd("setopt delimiter ''");<br>
+receiving_socket = listening_socket:accept()<br>
 ---<br>
-- true<br>
 ...<br>
 sending_socket:write(message)<br>
 ---<br>
@@ -2864,46 +2820,41 @@ counter = 0<br>
 fn = function(s) counter = 0; while true do s:write((tostring(counter)):rep(chan:get())); counter = counter + 1 end end<br>
 ---<br>
 ...<br>
-srv = nil<br>
+srv = socket.tcp_server('0.0.0.0', 0, fn)<br>
 ---<br>
 ...<br>
-test_run:cmd("setopt delimiter ';'")<br>
+s = socket.connect('localhost', srv:name().port)<br>
 ---<br>
-- true<br>
 ...<br>
-test_run:wait_cond(function()<br>
-    port = 32768 + math.random(0, 32767)<br>
-    srv = socket.tcp_server('0.0.0.0', port, fn)<br>
-    return srv ~= nil<br>
-end, WAIT_COND_TIME);<br>
+chan:put(5)<br>
 ---<br>
 - true<br>
 ...<br>
-receive1 = nil; receive2 = nil;<br>
+chan:put(5)<br>
 ---<br>
+- true<br>
 ...<br>
-if srv ~= nil then<br>
-    s = socket.connect('localhost', port)<br>
-    chan:put(5)<br>
-    chan:put(5)<br>
-    receive1 = s:receive(5)<br>
-    chan:put(5)<br>
-    s:settimeout(1)<br>
-    receive2 = s:receive('*a')<br>
-    s:close()<br>
-    srv:close()<br>
-end;<br>
+s:receive(5)<br>
 ---<br>
+- '00000'<br>
 ...<br>
-test_run:cmd("setopt delimiter ''");<br>
+chan:put(5)<br>
 ---<br>
 - true<br>
 ...<br>
-receive1<br>
+s:settimeout(1)<br>
 ---<br>
-- '00000'<br>
+- 1<br>
 ...<br>
-receive2<br>
+s:receive('*a')<br>
 ---<br>
 - '1111122222'<br>
 ...<br>
+s:close()<br>
+---<br>
+- 1<br>
+...<br>
+srv:close()<br>
+---<br>
+- true<br>
+...<br>
diff --git a/test/app/socket.test.lua b/test/app/socket.test.lua<br>
index 97dac794e..9ba6b2893 100644<br>
--- a/test/app/socket.test.lua<br>
+++ b/test/app/socket.test.lua<br>
@@ -91,9 +91,9 @@ s:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)<br>
 s:error()<br>
 s:bind('127.0.0.1', 0)<br>
 s:error()<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(128)<br>
 sevres = {}<br>
-type(require('fiber').create(function() s:readable(WAIT_COND_TIME) do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end))<br>
+type(require('fiber').create(function() s:readable() do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end))<br>
 #sevres<br><br>
 sc = socket('PF_INET', 'SOCK_STREAM', 'tcp')<br>
@@ -135,7 +135,7 @@ s:close()<br>
 s = socket('PF_INET', 'SOCK_STREAM', 'tcp')<br>
 s:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)<br>
 s:bind('127.0.0.1', 0)<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(128)<br><br>
 sc = socket('PF_INET', 'SOCK_STREAM', 'tcp')<br><br>
@@ -150,14 +150,14 @@ addr2.family == addr.family<br>
 sa:nonblock(1)<br>
 sa:read(8)<br>
 sa:read(3)<br>
-sc:writable(WAIT_COND_TIME)<br>
+sc:writable()<br>
 sc:write(', again')<br>
 sa:read(8)<br>
 sa:error()<br>
 string.len(sa:read(0))<br>
 type(sa:read(0))<br>
 sa:read(1, .01)<br>
-sc:writable(WAIT_COND_TIME)<br>
+sc:writable()<br><br>
 -- gh-3979 Check for errors when argument is negative.<br><br>
@@ -170,7 +170,7 @@ sc:send('abc')<br>
 sa:read(3)<br><br>
 sc:send('Hello')<br>
-sa:readable(WAIT_COND_TIME)<br>
+sa:readable()<br>
 sa:recv()<br>
 sa:recv()<br><br>
@@ -198,14 +198,14 @@ path = 'tarantool-test-socket'<br>
 os.remove(path)<br>
 s:bind('unix/', path)<br>
 sc ~= nil<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(1234)<br><br>
 sc = socket('PF_UNIX', 'SOCK_STREAM', 0)<br>
 sc:nonblock(true)<br>
 sc:sysconnect('unix/', path)<br>
 sc:error()<br><br>
-s:readable(WAIT_COND_TIME)<br>
+s:readable()<br>
 sa = s:accept()<br>
 sa:nonblock(true)<br>
 sa:send('Hello, world')<br>
@@ -243,7 +243,7 @@ sc:getsockopt('SOL_SOCKET', 'SO_ERROR')<br>
 sc:nonblock(true)<br>
 sc:sysconnect('127.0.0.1', 3458) or errno() == errno.EINPROGRESS or errno() == errno.ECONNREFUSED<br>
 string.match(tostring(sc), ', peer') == nil<br>
-sc:writable(WAIT_COND_TIME)<br>
+sc:writable()<br>
 string.match(tostring(sc), ', peer') == nil<br>
 socket_error = sc:getsockopt('SOL_SOCKET', 'SO_ERROR')<br>
 socket_error == errno.ECONNREFUSED or socket_error == 0<br>
@@ -307,7 +307,7 @@ socket.tcp_connect('127.0.0.1', 80, 0.00000000001)<br>
 s = socket('AF_INET', 'SOCK_STREAM', 'tcp')<br>
 s:bind('127.0.0.1', 0)<br>
 port = s:name().port<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen()<br>
 sc, e = socket.tcp_connect('127.0.0.1', port), errno()<br>
 sc ~= nil<br>
 e == 0<br>
@@ -321,7 +321,7 @@ _ = os.remove(path)<br>
 s = socket('AF_UNIX', 'SOCK_STREAM', 0)<br>
 s:bind('unix/', path)<br>
 socket.tcp_connect('unix/', path), errno() == errno.ECONNREFUSED<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen()<br>
 sc, e = socket.tcp_connect('unix/', path), errno()<br>
 sc ~= nil<br>
 e<br>
@@ -342,26 +342,13 @@ s = nil<br><br>
 -- random port<br>
 master = socket('PF_INET', 'SOCK_STREAM', 'tcp')<br>
-master:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)<br>
-math.randomseed(fiber.time())<br>
-port = 32768 + math.random(0, 32767)<br>
--- SO_REUSEADDR allows to bind to the same source addr:port twice,<br>
--- so listen() can return EADDRINUSE and so we check it within<br>
--- wait_cond().<br>
+master:bind('127.0.0.1', 0)<br>
+port = master:name().port</div></div></div></div></blockquote>1. We need to start listening here.<br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15765410101821021160_BODY"><br>
 test_run:cmd("setopt delimiter ';'")<br>
-test_run:wait_cond(function()<br>
-    local ok = master:bind('127.0.0.1', port)<br>
-    local ok = ok and master:listen(WAIT_COND_TIME)<br>
-    if not ok then<br>
-        port = 32768 + math.random(32768)<br>
-        return false, master:error()<br>
-    end<br>
-    return true<br>
-end, WAIT_COND_TIME);<br>
 function gh361()<br>
     local s = socket('PF_INET', 'SOCK_STREAM', 'tcp')<br>
     s:sysconnect('127.0.0.1', port)<br>
-    s:wait(WAIT_COND_TIME)<br>
+    s:wait()<br>
     res = s:read(1200)<br>
 end;<br>
 test_run:cmd("setopt delimiter ''");<br>
@@ -378,11 +365,11 @@ s:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)<br>
 s:error()<br>
 s:bind('unix/', path)<br>
 s:error()<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(128)<br>
 test_run:cmd("setopt delimiter ';'")<br>
 f = fiber.create(function()<br>
     for i=1,2 do<br>
-        s:readable(WAIT_COND_TIME)<br>
+        s:readable()<br>
         local sc = s:accept()<br>
         sc:write('ok!')<br>
         sc:shutdown()<br>
@@ -507,7 +494,7 @@ _ = os.remove(path)<br>
 -- Test that socket is closed on GC<br>
 s = socket('AF_UNIX', 'SOCK_STREAM', 0)<br>
 s:bind('unix/', path)<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen()<br>
 s = nil<br>
 while socket.tcp_connect('unix/', path) do collectgarbage('collect') end<br>
 _ = os.remove(path)<br>
@@ -603,7 +590,7 @@ s:setoption('tcp-nodelay', true)<br>
 s:setoption('unknown', true)<br>
 s:bind('127.0.0.1', 0)<br>
 s:bind('127.0.0.1', 0) -- error handling<br>
-s:listen(WAIT_COND_TIME)<br>
+s:listen(10)<br>
 s -- transformed to tcp{server} socket<br>
 host, port, family = s:getsockname()<br>
 host == '127.0.0.1', type(port) == 'string', family == 'inet'<br>
@@ -763,11 +750,7 @@ end;<br>
 test_run:cmd("setopt delimiter ''");<br><br>
 receiving_socket = socket('AF_INET', 'SOCK_DGRAM', 'udp')<br>
-test_run:cmd("setopt delimiter ';'")<br>
-test_run:wait_cond(function()<br>
-    return receiving_socket:bind('127.0.0.1', 32768 + math.random(0, 32767))<br>
-end, WAIT_COND_TIME);<br>
-test_run:cmd("setopt delimiter ''");<br>
+receiving_socket:bind('127.0.0.1', 0)<br>
 receiving_socket_port = receiving_socket:name().port<br>
 sending_socket = socket('AF_INET', 'SOCK_DGRAM', 'udp')<br><br>
@@ -902,20 +885,13 @@ message = string.rep('x', message_len)<br><br>
 listening_socket = socket('AF_INET', 'SOCK_STREAM', 'tcp')<br>
 listening_socket:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)<br>
-test_run:cmd("setopt delimiter ';'")<br>
-test_run:wait_cond(function()<br>
-    return listening_socket:bind('127.0.0.1', 32768 + math.random(0, 32767))<br>
-end, WAIT_COND_TIME);<br>
-test_run:cmd("setopt delimiter ''");<br>
-listening_socket:listen(WAIT_COND_TIME)<br>
+listening_socket:bind('127.0.0.1', 0)<br>
+listening_socket:listen()<br>
 listening_socket_port = listening_socket:name().port<br>
 sending_socket = socket('AF_INET', 'SOCK_STREAM', 'tcp')<br>
 sending_socket:sysconnect('127.0.0.1', listening_socket_port) or errno() == errno.EINPROGRESS<br>
-test_run:cmd("setopt delimiter ';'")<br>
-receiving_socket = test_run:wait_cond(function()<br>
-    return listening_socket:accept()<br>
-end, WAIT_COND_TIME);<br>
-test_run:cmd("setopt delimiter ''");<br>
+listening_socket:readable(WAIT_COND_TIME)<br>
+receiving_socket = listening_socket:accept()<br>
 sending_socket:write(message)<br><br>
 -- case: recvfrom reads first 512 bytes from the message with tcp<br>
@@ -983,26 +959,14 @@ test_run:cmd("clear filter")<br>
 chan = fiber.channel()<br>
 counter = 0<br>
 fn = function(s) counter = 0; while true do s:write((tostring(counter)):rep(chan:get())); counter = counter + 1 end end<br>
-srv = nil<br>
-test_run:cmd("setopt delimiter ';'")<br>
-test_run:wait_cond(function()<br>
-    port = 32768 + math.random(0, 32767)<br>
-    srv = socket.tcp_server('0.0.0.0', port, fn)<br>
-    return srv ~= nil<br>
-end, WAIT_COND_TIME);<br>
-receive1 = nil; receive2 = nil;<br>
-if srv ~= nil then<br>
-    s = socket.connect('localhost', port)<br>
-    chan:put(5)<br>
-    chan:put(5)<br>
-    receive1 = s:receive(5)<br>
-    chan:put(5)<br>
-    s:settimeout(1)<br>
-    receive2 = s:receive('*a')<br>
-    s:close()<br>
-    srv:close()<br>
-end;<br>
-test_run:cmd("setopt delimiter ''");<br>
-receive1<br>
-receive2<br>
+srv = socket.tcp_server('0.0.0.0', 0, fn)<br>
+s = socket.connect('localhost', srv:name().port)<br>
+chan:put(5)<br>
+chan:put(5)<br>
+s:receive(5)<br>
+chan:put(5)<br>
+s:settimeout(1)<br>
+s:receive('*a')<br>
+s:close()<br>
+srv:close()</div></div></div></div></blockquote><p>2. It still seems to me that we don't want to hang on chan:put() even<br>in case server fails to start, as far as it makes output less clear.<br>However, alternative construction also seems to be quite confusing.<br>Considering that it shouldn't also fail any more, i see why it is<br>better to leave unwrapped construction.</p><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15765410101821021160_BODY"><br><br>
===========================================================================<br><br>
commit 5a5cd01a0c665f2438e05feb46dde964828f6c01<br>
Author: Vladislav Shpilevoy <<a href="mailto:v.shpilevoy@tarantool.org">v.shpilevoy@tarantool.org</a>><br>
Date:   Tue Dec 17 00:20:01 2019 +0100<br><br>
    Make UDP more table on Mac<br><br>
diff --git a/test/app/socket.result b/test/app/socket.result<br>
index 563519315..cb3897ee1 100644<br>
--- a/test/app/socket.result<br>
+++ b/test/app/socket.result<br>
@@ -2282,7 +2282,9 @@ sendto_zero(sending_socket, '127.0.0.1', receiving_socket_port)<br>
 ---<br>
 - 0<br>
 ...<br>
-received_message = receiving_socket:recv()<br>
+received_message = test_run:wait_cond(function()        \<br>
+    return receiving_socket:recv()                      \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
@@ -2305,7 +2307,9 @@ sendto_zero(sending_socket, '127.0.0.1', receiving_socket_port)<br>
 ---<br>
 - 0<br>
 ...<br>
-received_message, from = receiving_socket:recvfrom()<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom()                  \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
@@ -2382,7 +2386,9 @@ sendto_zero(sending_socket, '127.0.0.1', receiving_socket_port)<br>
 ---<br>
 - 0<br>
 ...<br>
-received_message = receiving_socket:recv(512)<br>
+received_message = test_run:wait_cond(function()        \<br>
+    return receiving_socket:recv(512)                   \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
@@ -2405,7 +2411,9 @@ sendto_zero(sending_socket, '127.0.0.1', receiving_socket_port)<br>
 ---<br>
 - 0<br>
 ...<br>
-received_message, from = receiving_socket:recvfrom(512)<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom(512)               \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
@@ -2442,7 +2450,9 @@ sending_socket:sendto('127.0.0.1', receiving_socket_port, message)<br>
 ---<br>
 - 1025<br>
 ...<br>
-received_message = receiving_socket:recv()<br>
+received_message = test_run:wait_cond(function()        \<br>
+    return receiving_socket:recv()                      \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
@@ -2474,7 +2484,9 @@ sending_socket:sendto('127.0.0.1', receiving_socket_port, message)<br>
 ---<br>
 - 1025<br>
 ...<br>
-received_message, from = receiving_socket:recvfrom()<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom()                  \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
@@ -2513,7 +2525,9 @@ sending_socket:sendto('127.0.0.1', receiving_socket_port, message)<br>
 ---<br>
 - 1025<br>
 ...<br>
-received_message = receiving_socket:recv(512)<br>
+received_message = test_run:wait_cond(function()        \<br>
+    return receiving_socket:recv(512)                   \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
@@ -2556,7 +2570,9 @@ sending_socket:sendto('127.0.0.1', receiving_socket_port, message)<br>
 ---<br>
 - 1025<br>
 ...<br>
-received_message, from = receiving_socket:recvfrom(512)<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom(512)               \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
@@ -2645,7 +2661,9 @@ sending_socket:write(message)<br>
 - 513<br>
 ...<br>
 -- case: recvfrom reads first 512 bytes from the message with tcp<br>
-received_message, from = receiving_socket:recvfrom()<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom()                  \<br>
+end, WAIT_COND_TIME)<br>
 ---<br>
 ...<br>
 e = receiving_socket:errno()<br>
diff --git a/test/app/socket.test.lua b/test/app/socket.test.lua<br>
index 9ba6b2893..a0803519d 100644<br>
--- a/test/app/socket.test.lua<br>
+++ b/test/app/socket.test.lua<br>
@@ -772,7 +772,9 @@ e == errno.EAGAIN -- expected true<br><br>
 -- case: recv, zero datagram<br>
 sendto_zero(sending_socket, '127.0.0.1', receiving_socket_port)<br>
-received_message = receiving_socket:recv()<br>
+received_message = test_run:wait_cond(function()        \<br>
+    return receiving_socket:recv()                      \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == '' -- expected true<br>
 received_message<br>
@@ -780,7 +782,9 @@ e == 0 -- expected true<br><br>
 -- case: recvfrom, zero datagram<br>
 sendto_zero(sending_socket, '127.0.0.1', receiving_socket_port)<br>
-received_message, from = receiving_socket:recvfrom()<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom()                  \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == '' -- expected true<br>
 received_message<br>
@@ -806,7 +810,9 @@ e == errno.EAGAIN -- expected true<br><br>
 -- case: recv, zero datagram, explicit size<br>
 sendto_zero(sending_socket, '127.0.0.1', receiving_socket_port)<br>
-received_message = receiving_socket:recv(512)<br>
+received_message = test_run:wait_cond(function()        \<br>
+    return receiving_socket:recv(512)                   \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == '' -- expected true<br>
 received_message<br>
@@ -814,7 +820,9 @@ e == 0 -- expected true<br><br>
 -- case: recvfrom, zero datagram, explicit size<br>
 sendto_zero(sending_socket, '127.0.0.1', receiving_socket_port)<br>
-received_message, from = receiving_socket:recvfrom(512)<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom(512)               \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == '' -- expected true<br>
 received_message<br>
@@ -827,7 +835,9 @@ message = string.rep('x', message_len)<br><br>
 -- case: recv, non-zero length datagram, the buffer size should be evaluated<br>
 sending_socket:sendto('127.0.0.1', receiving_socket_port, message)<br>
-received_message = receiving_socket:recv()<br>
+received_message = test_run:wait_cond(function()        \<br>
+    return receiving_socket:recv()                      \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == message -- expected true<br>
 received_message:len()<br>
@@ -838,7 +848,9 @@ e<br>
 -- case: recvfrom, non-zero length datagram, the buffer size should be<br>
 -- evaluated<br>
 sending_socket:sendto('127.0.0.1', receiving_socket_port, message)<br>
-received_message, from = receiving_socket:recvfrom()<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom()                  \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == message -- expected true<br>
 received_message:len()<br>
@@ -850,7 +862,9 @@ e<br><br>
 -- case: recv truncates a datagram larger then the buffer of an explicit size<br>
 sending_socket:sendto('127.0.0.1', receiving_socket_port, message)<br>
-received_message = receiving_socket:recv(512)<br>
+received_message = test_run:wait_cond(function()        \<br>
+    return receiving_socket:recv(512)                   \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == message:sub(1, 512) -- expected true<br>
 received_message:len() == 512 -- expected true<br>
@@ -866,7 +880,9 @@ message = string.rep('y', message_len)<br><br>
 -- case: recvfrom truncates a datagram larger then the buffer of an explicit size<br>
 sending_socket:sendto('127.0.0.1', receiving_socket_port, message)<br>
-received_message, from = receiving_socket:recvfrom(512)<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom(512)               \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == message:sub(1, 512) -- expected true<br>
 received_message:len() == 512 -- expected true<br>
@@ -895,7 +911,9 @@ receiving_socket = listening_socket:accept()<br>
 sending_socket:write(message)<br><br>
 -- case: recvfrom reads first 512 bytes from the message with tcp<br>
-received_message, from = receiving_socket:recvfrom()<br>
+received_message, from = test_run:wait_cond(function()  \<br>
+    return receiving_socket:recvfrom()                  \<br>
+end, WAIT_COND_TIME)<br>
 e = receiving_socket:errno()<br>
 received_message == message:sub(1, 512) -- expected true<br>
 received_message:len() == 512 -- expected true<br></div></div></div></div></blockquote>
<br>
<br>-- <br>Ilya Kosarev<br></BODY></HTML>