--- /dev/null
+#EXCLUDE_TARGETS=osx
+varnishtest "Unique identifiers of the master and worker processes"
+
+feature ignore_unknown_macro
+
+# h1 forces the worker's ID so that it can be matched exactly, while the
+# master's one is randomly generated, hence only its format is checked: it must
+# be a UUID version 7, whose version nibble is 7 and whose variant bits are 10.
+haproxy h1 -Ws -S -conf {
+ global
+ .if feature(THREAD)
+ thread-groups 1
+ .endif
+ worker-id my-worker.1
+
+ defaults
+ mode http
+ timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+
+ frontend myfrontend
+ bind "fd@${my_fe}"
+ stats enable
+ stats uri /stats
+ stats show-node
+ http-request return status 200 hdr x-worker "%[worker_id]" hdr x-cfg-worker "$HAPROXY_WORKER_ID" hdr x-master "%[master_id]" if { path / }
+} -start
+
+# h2 has no master and lets its worker ID be generated, so that the generated
+# value and its exported copy can be compared to each other.
+haproxy h2 -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 myfrontend
+ bind "fd@${my_fe}"
+ stats enable
+ stats uri /stats
+ stats show-node
+ http-request return status 200 hdr x-worker "%[worker_id]" hdr x-cfg-worker "$HAPROXY_WORKER_ID" hdr x-master "%[master_id]" if { path / }
+} -start
+
+# the forced worker ID is seen both by the sample fetch function and by
+# $HAPROXY_WORKER_ID, and the master's one is a UUID v7
+client c1 -connect ${h1_my_fe_sock} {
+ txreq -url /
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-worker == "my-worker.1"
+ expect resp.http.x-cfg-worker == "my-worker.1"
+ expect resp.http.x-master ~ "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+} -run
+
+# "stats show-node" reports the master first, then the worker
+client c2 -connect ${h1_my_fe_sock} {
+ txreq -url /stats
+ rxresp
+ expect resp.status == 200
+ expect resp.body ~ "<b>master-id = </b> [0-9a-f-]{36}; <b>worker-id = </b> my-worker.1<br>"
+} -run
+
+# without a master, the "master_id" sample fetch function finds nothing, and
+# the generated worker ID is a UUID v7 which matches its exported copy
+client c3 -connect ${h2_my_fe_sock} {
+ txreq -url /
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-master == <undef>
+ expect resp.http.x-worker ~ "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+ expect resp.http.x-cfg-worker == resp.http.x-worker
+} -run
+
+# and only the worker is reported on the stats page
+client c4 -connect ${h2_my_fe_sock} {
+ txreq -url /stats
+ rxresp
+ expect resp.status == 200
+ expect resp.body ~ "<b>worker-id = </b> [0-9a-f-]{36}<br>"
+ expect resp.body !~ "master-id"
+} -run
+
+haproxy h2 -wait
+
+haproxy h1 -mcli {
+ delay 0.1
+ send "show env"
+ expect ~ ".*\nHAPROXY_MASTER_ID=[0-9a-f-]{36}\n.*"
+ send "@1 show env"
+ expect ~ ".*\nHAPROXY_WORKER_ID=my-worker.1\n.*"
+ send "@1 show info"
+ expect ~ ".*\nMaster_id: [0-9a-f-]{36}\n.*"
+ send "@1 show info"
+ expect ~ ".*\nWorker_id: my-worker.1\n.*"
+} -wait