Newer
Older
openstack-caracal-dc-dc / tests / geneve-encap-assert / run-tests.sh
#!/usr/bin/env bash
# tests/geneve-encap-assert/run-tests.sh -- offline harness for
# scripts/geneve-encap-assert.sh. Self-contained: fixtures are written to a
# temp dir; the pure assertion logic (C1 family consistency, C2 tunnel ofport
# health) runs for real against them. Every check is proven in its FAILING
# direction (a checker that cannot fail is not a gate). Exit: 0 all pass | 1 any
# case failed. ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT="$HERE/../../scripts/geneve-encap-assert.sh"
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
PASS=0; FAIL=0

run() { # run <want_rc> <regex> <label> -- args...
  local want="$1" rx="$2" label="$3"; shift 3
  local out rc
  out="$(bash "$SCRIPT" "$@" 2>&1)"; rc=$?
  if [[ "$rc" == "$want" ]] && grep -qE "$rx" <<<"$out"; then
    echo "  PASS  $label"; PASS=$((PASS+1))
  else
    echo "  FAIL  $label (rc=$rc want=$want)"; echo "$out" | sed 's/^/        /'; FAIL=$((FAIL+1))
  fi
}

# --- fixtures ----------------------------------------------------------------
printf '%s\n' '2602:f3e2:f02:30::100' '2602:f3e2:f02:30::120' '2602:f3e2:f02:30::121' > "$TMP/encap_v6.txt"
printf '%s\n' '10.12.16.1' '10.12.16.2' '10.12.16.3'                                   > "$TMP/encap_v4.txt"
# the real 2026-08-08 split: control LXD v4 + compute metal v6
printf '%s\n' '10.12.16.1' '10.12.16.2' '2602:f3e2:f02:30::120' '2602:f3e2:f02:30::121' > "$TMP/encap_split.txt"
# bracketed v6 (as ovn-chassis 24.03 emits) -- still parses as v6 for C1
printf '%s\n' '[2602:f3e2:f02:30::120]' '[2602:f3e2:f02:30::121]'                       > "$TMP/encap_v6_brk.txt"
: > "$TMP/encap_empty.txt"

printf '%s\n' '14' '15' '16' '17' '18'      > "$TMP/of_ok.txt"      # all valid
printf '%s\n' '14' '-1' '16'                 > "$TMP/of_bad.txt"     # one invalid (bracket-bug signature)
: > "$TMP/of_empty.txt"

E6="--encap-ips $TMP/encap_v6.txt"; OK="--tunnel-ofports $TMP/of_ok.txt"

# --- C1/C2 clean PASS --------------------------------------------------------
run 0 'geneve-encap-assert: PASS' "T1 uniform-v6 encap + valid ofports PASS" $E6 $OK
run 0 'C1: all 3 chassis .* single-family \(v6\)' "T2 C1 reports single-family v6" $E6 $OK
run 0 'C2: all 5 .* ofport >= 0'                 "T3 C2 reports all ofports valid" $E6 $OK
run 0 'geneve-encap-assert: PASS' "T4 uniform-v4 encap also PASSes (consistency, not v6-hardcoded)" --encap-ips "$TMP/encap_v4.txt" $OK

# --- C1 FAILING direction: family split -------------------------------------
run 1 'C1: geneve encap SPLIT across families' "T5 split encap FAILS C1 (the 2026-08-08 root cause)" --encap-ips "$TMP/encap_split.txt" $OK

# --- C2 FAILING direction: ofport -1 (bracket bug) --------------------------
run 1 'C2: 1 of 3 geneve tunnels have ofport -1' "T6 ofport -1 FAILS C2 (the 2026-08-09 bracket bug)" $E6 --tunnel-ofports "$TMP/of_bad.txt"
# bracketed encap is single-family (C1 ok) but the bug shows as C2 ofport -1
run 1 'geneve-encap-assert: FAIL' "T7 bracketed-v6 encap + ofport -1 FAILS (C1 passes, C2 catches)" --encap-ips "$TMP/encap_v6_brk.txt" --tunnel-ofports "$TMP/of_bad.txt"
run 0 'C1: all 2 chassis .* single-family \(v6\)' "T8 bracketed v6 still parses as single-family v6 for C1" --encap-ips "$TMP/encap_v6_brk.txt" $OK

# --- --expect-family (ruled family) ------------------------------------------
run 0 'geneve-encap-assert: PASS' "T9 --expect-family v6 on v6 PASSes"  $E6 $OK --expect-family v6
run 1 'C1: encap family is .v4. but --expect-family=v6' "T10 --expect-family v6 on v4 FAILS" --encap-ips "$TMP/encap_v4.txt" $OK --expect-family v6

# --- refuse-not-pass on empty inputs ----------------------------------------
run 1 'C1: no chassis Encap.ip found' "T11 empty encap REFUSES (not pass)" --encap-ips "$TMP/encap_empty.txt" $OK
run 1 'C2: no geneve tunnel interfaces found' "T12 empty ofports REFUSES (not pass)" $E6 --tunnel-ofports "$TMP/of_empty.txt"

# --- usage/precondition (rc 2) ----------------------------------------------
run 2 'need --encap-ips' "T13 missing --encap-ips is usage (rc 2)" $OK
run 2 'need --tunnel-ofports' "T14 missing --tunnel-ofports is usage (rc 2)" $E6
run 2 'must be v6 or v4' "T15 bad --expect-family is usage (rc 2)" $E6 $OK --expect-family v5
run 2 'unknown arg' "T16 unknown arg is usage (rc 2)" $E6 $OK --bogus

echo "-----"
echo "geneve-encap-assert harness: $PASS passed, $FAIL failed"
[ "$FAIL" -eq 0 ]