Skip to content

Commit da5904d

Browse files
author
CodexM5
committed
test: prove VIP-source GARP on each ownership transition
1 parent 5ad76d6 commit da5904d

1 file changed

Lines changed: 34 additions & 6 deletions

File tree

‎tests/dataplane/integration/vip-standalone.sh‎

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ done
194194
# particular, some arping versions report failure for a sent unsolicited
195195
# packet because no reply is expected; an exit code alone cannot prove GARP.
196196
arping -V >"$run_dir/diagnostics/arping-version.txt" 2>&1 || true
197-
sudo timeout 40s tcpdump -l -nn -tt -i "$bridge" arp \
197+
sudo timeout 40s tcpdump -e -l -nn -tt -i "$bridge" arp \
198198
>"$run_dir/diagnostics/arp-packets.txt" \
199199
2>"$run_dir/diagnostics/tcpdump-stderr.txt" &
200200
capture_pid=$!
@@ -269,6 +269,34 @@ assert_no_overlap() {
269269
fi
270270
}
271271

272+
garp_count() {
273+
local node=$1 mac
274+
if [[ $node == a ]]; then
275+
mac=02:00:00:99:20:11
276+
else
277+
mac=02:00:00:99:20:12
278+
fi
279+
awk -v vip="$vip_ip" -v mac="$mac" '
280+
index($0, mac) && index($0, "who-has " vip) && index($0, "tell " vip) { count++ }
281+
END { print count + 0 }
282+
' "$run_dir/diagnostics/arp-packets.txt"
283+
}
284+
285+
wait_garp() {
286+
local label=$1 node=$2 previous=$3 count
287+
for _ in {1..30}; do
288+
count=$(garp_count "$node")
289+
if ((count > previous)); then
290+
echo "$(date +%s.%N) $label $node GARP observed" \
291+
>>"$run_dir/diagnostics/events.log"
292+
return 0
293+
fi
294+
sleep 0.2
295+
done
296+
echo "$label: no VIP-source GARP from $node observed on the bridge" >&2
297+
return 1
298+
}
299+
272300
monitor_overlap &
273301
monitor_pid=$!
274302
start_node a "$ns_a"
@@ -346,6 +374,7 @@ wait_single_owner() {
346374

347375
owner=$(wait_single_owner initial)
348376
assert_no_overlap
377+
wait_garp initial "$owner" 0
349378
wait_mysql "$vip_ip" 6000 initial-vip
350379
if [[ $owner == a ]]; then
351380
former=a
@@ -355,9 +384,11 @@ else
355384
new=a
356385
fi
357386
former_pid=$(cat "$run_dir/$former.pid")
387+
before_garp=$(garp_count "$new")
358388
sudo kill -INT "$former_pid"
359389
wait_single_owner after-controlled-close "$new" >/dev/null
360390
assert_no_overlap
391+
wait_garp after-controlled-close "$new" "$before_garp"
361392
wait_mysql "$vip_ip" 6000 controlled-failover
362393
for _ in {1..30}; do
363394
sudo kill -0 "$former_pid" 2>/dev/null || break
@@ -383,6 +414,7 @@ wait_mysql "$vip_ip" 6000 restart
383414
# Model a whole-node crash: terminate its process and remove its network link.
384415
# Process-only SIGKILL leaves an IP on a live Linux interface and is separately
385416
# documented as a remaining Go/Rust operational fencing gap.
417+
before_garp=$(garp_count "$former")
386418
sudo kill -KILL "$(cat "$run_dir/$new.pid")"
387419
if [[ $new == a ]]; then
388420
sudo ip link del "$host_a"
@@ -391,6 +423,7 @@ else
391423
fi
392424
wait_single_owner after-node-link-loss "$former" >/dev/null
393425
assert_no_overlap
426+
wait_garp after-node-link-loss "$former" "$before_garp"
394427
wait_mysql "$vip_ip" 6000 node-failover
395428
kill "$monitor_pid" 2>/dev/null || true
396429
wait "$monitor_pid" 2>/dev/null || true
@@ -399,9 +432,4 @@ kill "$capture_pid" 2>/dev/null || true
399432
wait "$capture_pid" 2>/dev/null || true
400433
capture_pid=
401434
assert_no_overlap
402-
if ! grep -F "tell $vip_ip" "$run_dir/diagnostics/arp-packets.txt" |
403-
grep -Fq "who-has $vip_ip"; then
404-
echo 'no gratuitous ARP announcement for the VIP observed on the bridge' >&2
405-
exit 1
406-
fi
407435
echo 'PASS: one VIP holder and SQL continuity through controlled close, restart and node/link loss'

0 commit comments

Comments
 (0)