Files
haproxy/reg-tests/stream/test_content_switching.vtc
Amaury Denoyelle 6870551a57 MEDIUM: proxy: force traffic on unpublished/disabled backends
A recent patch has introduced a new state for proxies : unpublished
backends. Such backends won't be eligilible for traffic, thus
use_backend/default_backend rules which target them won't match and
content switching rules processing will continue.

This patch defines a new frontend keywords 'force-be-switch'. This
keyword allows to ignore unpublished or disabled state. Thus,
use_backend/default_backend will match even if the target backend is
unpublished or disabled. This is useful to be able to test a backend
instance before exposing it outside.

This new keyword is converted into a persist rule of new type
PERSIST_TYPE_BE_SWITCH, stored in persist_rules list proxy member. This
is the only persist rule applicable to frontend side. Prior to this
commit, pure frontend proxies persist_rules list were always empty.

This new features requires adjustment in process_switching_rules(). Now,
when a use_backend/default_backend rule matches with an non eligible
backend, frontend persist_rules are inspected to detect if a
force-be-switch is present so that the backend may be selected.
2026-01-15 09:08:19 +01:00

173 lines
4.1 KiB
Plaintext

varnishtest "Ensure switching-rules conformance with backend eligibility"
feature ignore_unknown_macro
haproxy hsrv -conf {
global
.if feature(THREAD)
thread-groups 1
.endif
defaults
mode http
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
frontend fe
bind "fd@${feS}"
http-request return status 200 hdr "x-be" "li"
} -start
haproxy h1 -conf {
global
.if feature(THREAD)
thread-groups 1
.endif
defaults
mode http
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
frontend fe
bind "fd@${fe1S}"
use_backend %[req.hdr("x-target")] if { req.hdr("x-dyn") "1" }
use_backend be if { req.hdr("x-target") "be" }
frontend fe_default
bind "fd@${fe2S}"
force-be-switch if { req.hdr("x-force") "1" }
use_backend %[req.hdr("x-target")] if { req.hdr("x-dyn") "1" }
use_backend be_disabled if { req.hdr("x-target") "be_disabled" }
use_backend be
use_backend be2
default_backend be_default
listen li
bind "fd@${liS}"
use_backend %[req.hdr("x-target")] if { req.hdr("x-dyn") "1" }
server srv ${hsrv_feS_sock}
backend be
http-request return status 200 hdr "x-be" %[be_name]
backend be2
http-request return status 200 hdr "x-be" %[be_name]
backend be_disabled
disabled
http-request return status 200 hdr "x-be" %[be_name]
backend be_default
http-request return status 200 hdr "x-be" %[be_name]
} -start
client c1 -connect ${h1_fe1S_sock} {
# Dynamic rule matching
txreq -hdr "x-dyn: 1" -hdr "x-target: be"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be"
# Dynamic rule no match -> 503 expected
txreq -hdr "x-dyn: 1" -hdr "x-target: be_unknown"
rxresp
expect resp.status == 503
} -run
# Connect to frontend with default backend set
client c2 -connect ${h1_fe2S_sock} {
# Dynamic rule matching
txreq -hdr "x-dyn: 1" -hdr "x-target: be"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be"
# Dynamic rule no match -> use default backend
txreq -hdr "x-dyn: 1" -hdr "x-target: be_unknown"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be_default"
# Static rule on disabled backend -> continue to next rule
txreq -hdr "x-target: be_disabled"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be"
} -run
# Connect to listen proxy type
client c3 -connect ${h1_liS_sock} {
# Dynamic rule matching
txreq -hdr "x-dyn: 1" -hdr "x-target: be"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be"
# Dynamic rule no match -> stay on current proxy instance
txreq -hdr "x-dyn: 1" -hdr "x-target: be_unknown"
rxresp
expect resp.status == 200
expect resp.http.x-be == "li"
} -run
haproxy h1 -cli {
send "unpublish backend be_unknown"
expect ~ "No such backend."
send "unpublish backend be_disabled"
expect ~ "No effect on a disabled backend."
send "unpublish backend be"
expect ~ "Backend unpublished."
}
client c4 -connect ${h1_fe2S_sock} {
# Static rule on unpublished backend -> continue to next rule
txreq
rxresp
expect resp.status == 200
expect resp.http.x-be == "be2"
# Dynamic rule on unpublished backend -> continue to next rule
txreq -hdr "x-dyn: 1" -hdr "x-target: be"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be2"
# Static rule matching on unpublished backend with force-be-switch
txreq -hdr "x-force: 1"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be"
# Dynamic rule matching on unpublished backend with force-be-switch
txreq -hdr "x-dyn: 1" -hdr "x-target: be" -hdr "x-force: 1"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be"
} -run
haproxy h1 -cli {
send "publish backend be"
expect ~ "Backend published."
}
client c5 -connect ${h1_fe2S_sock} {
# Static rule matching on republished backend
txreq -hdr "x-target: be"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be"
# Dynamic rule matching on republished backend
txreq -hdr "x-dyn: 1" -hdr "x-target: be"
rxresp
expect resp.status == 200
expect resp.http.x-be == "be"
} -run