Skip to content

Commit 5b704ac

Browse files
sergepetrenkoylobankov
authored andcommitted
Fix random test hangs when using proxy module
When one end of the connection is closed for some reason, the proxy should close the other end as well. Otherwise random hangs are possible when a client doesn't notice that the server has closed the socket. Previously clients never noticed leader disconnect (they only noticed that the heartbeats were missing), and some tests relied on that behaviour while proxy is paused. To preserve it, do not close the sockets while proxy is paused. Resolves #298
1 parent 045dc8d commit 5b704ac

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

luatest/replica_conn.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ function Connection:initialize()
3737
self.process_client = {
3838
pre = nil,
3939
func = self.forward_to_server,
40-
post = self.close_client_socket,
40+
post = self.stop,
4141
}
4242
end
4343

4444
if self.process_server == nil then
4545
self.process_server = {
4646
pre = nil,
4747
func = self.forward_to_client,
48-
post = self.close_server_socket,
48+
post = self.stop,
4949
}
5050
end
5151

@@ -71,7 +71,7 @@ function Connection:process_socket(sock, process)
7171
local f = fiber.new(function()
7272
if process.pre ~= nil then process.pre(self) end
7373

74-
while sock:peer() do
74+
while sock:peer() or not self.running do
7575
if not self.running then
7676
fiber.sleep(TIMEOUT)
7777
elseif sock:readable(TIMEOUT) then

test/proxy_test.lua

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
local t = require('luatest')
22
local proxy = require('luatest.replica_proxy')
33
local utils = require('luatest.utils')
4+
local replica_set = require('luatest.replica_set')
5+
local server = require('luatest.server')
6+
7+
local fiber = require('fiber')
48

59
local g = t.group('proxy-version-check')
610

@@ -14,3 +18,66 @@ g.test_proxy_errors = function()
1418
server_socket_path = 'somepath'
1519
})
1620
end
21+
22+
local g1 = t.group('proxy', {
23+
{is_paused = true},
24+
{is_paused = false}
25+
})
26+
27+
g1.before_all(function(cg)
28+
-- Proxy only works on tarantool 2.10+
29+
t.run_only_if(utils.version_ge(utils.get_tarantool_version(),
30+
utils.version(2, 10, 1)),
31+
[[Proxy works on Tarantool 2.10.1+.
32+
See tarantool/tarantool@57ecb6cd90b4 for details]])
33+
cg.rs = replica_set:new{}
34+
cg.box_cfg = {
35+
replication_timeout = 0.1,
36+
replication = {
37+
server.build_listen_uri('server2_proxy', cg.rs.id),
38+
},
39+
}
40+
cg.server1 = cg.rs:build_and_add_server{
41+
alias = 'server1',
42+
box_cfg = cg.box_cfg,
43+
}
44+
cg.box_cfg.replication = nil
45+
cg.server2 = cg.rs:build_and_add_server{
46+
alias = 'server2',
47+
box_cfg = cg.box_cfg,
48+
}
49+
cg.proxy = proxy:new{
50+
client_socket_path = server.build_listen_uri('server2_proxy', cg.rs.id),
51+
server_socket_path = server.build_listen_uri('server2', cg.rs.id),
52+
}
53+
t.assert(cg.proxy:start{force = true}, 'Proxy is started')
54+
cg.rs:start{}
55+
end)
56+
57+
g1.test_server_disconnect_is_noticed = function(cg)
58+
local id = cg.server2:get_instance_id()
59+
t.helpers.retrying({}, cg.server1.assert_follows_upstream, cg.server1, id)
60+
if cg.params.is_paused then
61+
cg.proxy:pause()
62+
end
63+
cg.server2:stop()
64+
fiber.sleep(cg.box_cfg.replication_timeout)
65+
local upstream = cg.server1:exec(function(upstream_id)
66+
return box.info.replication[upstream_id].upstream
67+
end, {id})
68+
if cg.params.is_paused then
69+
t.assert_equals(upstream.status, 'follow',
70+
'Server disconnect is not noticed')
71+
else
72+
t.assert_equals(upstream.system_message, 'Broken pipe',
73+
'Server disconnect is noticed')
74+
end
75+
if cg.params.is_paused then
76+
cg.proxy:resume()
77+
end
78+
cg.server2:start()
79+
end
80+
81+
g1.after_all(function(cg)
82+
cg.rs:drop()
83+
end)

0 commit comments

Comments
 (0)