REGTESTS: abortonclose: Fix some race conditions

Depending on the timing, the second client that should be reported as a
client abort during connection attempt ("CC--" termination state) is
sometime logged as a server close ("SC--" termination state) instead. It
happens because sometime the connection failure to the server s1 is detected
by haproxy before the client c2 aborts. There is no retries and the
connection timeout is set to 100ms. So, to work, the client abort must be
performed and detected by haproxy in less than 100ms.

To fix the issue, the c2 client is now routed to a backend with a connection
timeout set to 1 second and 10 retries. It should be large enough to detect
the client aborts (~10s)

In addition, there is another race condition when the script is
started. sometime, server s1 is not stopped when the first client sends its
request. So a barrier was added to be sure it is stopped before starting to
send requests. And we wait to be sure the server is detected as DOWN to
unblock the barrier. It is performed by a dedicated backend with an
healthcheck on the server s1.

This patch should solve issue #1664.
This commit is contained in:
Christopher Faulet 2022-05-17 15:08:22 +02:00
parent bc684acae7
commit 96816b0755

View File

@ -7,10 +7,12 @@ feature ignore_unknown_macro
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'"
#REGTEST_TYPE=slow #REGTEST_TYPE=slow
# b0 : Wait s1 was detected as DOWN to be sure it is stopped
# b1 : Don't send /c4 before /c3 was received by s2 server # b1 : Don't send /c4 before /c3 was received by s2 server
# b2 : Don't finish c2 before c1 and c3 before c4 (from syslog POV) # b2 : Don't finish c2 before c1 and c3 before c4 (from syslog POV)
# b3 : finish c3 before s2 # b3 : finish c3 before s2
barrier b0 cond 2 -cyclic
barrier b1 cond 2 -cyclic barrier b1 cond 2 -cyclic
barrier b2 cond 2 -cyclic barrier b2 cond 2 -cyclic
barrier b3 cond 2 -cyclic barrier b3 cond 2 -cyclic
@ -32,11 +34,15 @@ server s2 {
} -start } -start
syslog S -level info { syslog S -level info {
recv alert
expect ~ "[^:\\[ ]*\\[[0-9]*\\]: Server check/srv1 is DOWN.*"
barrier b0 sync
recv recv
expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1/srv1 [0-9]*/[0-9]*/-1/-1/[0-9]* 503 .* - - SC-- .* .* \"GET /c1 HTTP/1\\.1\"" expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1_1/srv1 [0-9]*/[0-9]*/-1/-1/[0-9]* 503 .* - - SC-- .* .* \"GET /c1 HTTP/1\\.1\""
barrier b2 sync barrier b2 sync
recv recv
expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1/srv1 [0-9]*/[0-9]*/-1/-1/[0-9]* -1 .* - - CC-- .* .* \"GET /c2 HTTP/1\\.1\"" expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1_2/srv1 [0-9]*/[0-9]*/-1/-1/[0-9]* -1 .* - - CC-- .* .* \"GET /c2 HTTP/1\\.1\""
recv recv
expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be2/<NOSRV> [0-9]*/[0-9]*/-1/-1/[0-9]* -1 .* - - CQ-- .* .* \"GET /c4 HTTP/1\\.1\"" expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be2/<NOSRV> [0-9]*/[0-9]*/-1/-1/[0-9]* -1 .* - - CQ-- .* .* \"GET /c4 HTTP/1\\.1\""
@ -65,7 +71,8 @@ haproxy h1 -conf {
option httplog option httplog
log ${S_addr}:${S_port} local0 debug err log ${S_addr}:${S_port} local0 debug err
bind "fd@${fe1}" bind "fd@${fe1}"
use_backend be1 use_backend be1_1 if { path /c1 }
use_backend be1_2 if { path /c2 }
frontend fe2 frontend fe2
option httplog option httplog
@ -73,13 +80,25 @@ haproxy h1 -conf {
bind "fd@${fe2}" bind "fd@${fe2}"
use_backend be2 use_backend be2
backend be1 backend be1_1
server srv1 ${s1_addr}:${s1_port}
backend be1_2
timeout connect 1s
retries 10
server srv1 ${s1_addr}:${s1_port} server srv1 ${s1_addr}:${s1_port}
backend be2 backend be2
server srv1 ${s2_addr}:${s2_port} maxconn 1 server srv1 ${s2_addr}:${s2_port} maxconn 1
backend check
server srv1 ${s1_addr}:${s1_port} check
log ${S_addr}:${S_port} local0 debug alert
} -start } -start
# Wait s1 was detected as DOWN
barrier b0 sync
# No server, wait all connection retries : SC-- # No server, wait all connection retries : SC--
client c1 -connect ${h1_fe1_sock} { client c1 -connect ${h1_fe1_sock} {
txreq -url /c1 txreq -url /c1