mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
The mesh-public profile ran in neither runner: ci-local's static suite list carries only static-mesh and static-chain, and the GitHub matrix has only mesh and chain. It also added no coverage over static-mesh. ping-test.sh and iperf-test.sh branched mesh and mesh-public together and exercised the same 20 directed pairs among node-a through node-e, and no script referenced the external node at all. The convergence waits even used mesh's peer counts rather than mesh-public's, so the extra link to the public node was never counted, let alone asserted. Running it would therefore have added a dependency on a live internet host (test-us01.fips.network) in exchange for zero additional assertions. Remove the topology, its five compose services, the script branches that aliased it to mesh, and the documentation rows. An invocation using the old profile name now fails on ping-test.sh's unknown-profile guard instead of silently behaving as mesh. The config generator's external-node support (external_ip, is_external_node) stays. It has no consumer now, but it is woven into the config path every remaining topology uses, so removing it would put the gating suites at risk for no present gain.
134 lines
4.6 KiB
Bash
Executable File
134 lines
4.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# End-to-end iperf3 bandwidth test between FIPS nodes via DNS resolution.
|
|
# Usage: ./iperf-test.sh [mesh|chain] [--live]
|
|
#
|
|
# Requires containers to be running:
|
|
# docker compose --profile mesh up -d
|
|
# ./scripts/iperf-test.sh mesh
|
|
# ./scripts/iperf-test.sh mesh --live # Show live iperf3 output
|
|
set -e
|
|
|
|
# Exit entire script on Ctrl+C
|
|
trap 'echo ""; echo "Test interrupted"; exit 130' INT
|
|
|
|
PROFILE="${1:-mesh}"
|
|
LIVE_OUTPUT=false
|
|
if [ "$2" = "--live" ] || [ "$1" = "--live" ]; then
|
|
LIVE_OUTPUT=true
|
|
[ "$1" = "--live" ] && PROFILE="mesh"
|
|
fi
|
|
|
|
DURATION="${DURATION:-10}"
|
|
PARALLEL="${PARALLEL:-8}"
|
|
SETTLE_SECONDS="${SETTLE_SECONDS:-3}"
|
|
IPERF_TIMEOUT="${IPERF_TIMEOUT:-$((DURATION + 30))}"
|
|
PASSED=0
|
|
FAILED=0
|
|
|
|
# Node identities (from generated env file)
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ENV_FILE="$SCRIPT_DIR/../generated-configs${FIPS_CI_NAME_SUFFIX:-}/npubs.env"
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
echo "Error: $ENV_FILE not found. Run generate-configs.sh first." >&2
|
|
exit 1
|
|
fi
|
|
# shellcheck source=../generated-configs/npubs.env
|
|
source "$ENV_FILE"
|
|
|
|
iperf_test() {
|
|
local server_node="$1"
|
|
local client_node="$2"
|
|
local dest_npub="$3"
|
|
local label="$4"
|
|
|
|
echo ""
|
|
echo "=== $label ==="
|
|
|
|
# iperf3 server is already running in daemon mode in each container
|
|
|
|
if [ "$LIVE_OUTPUT" = true ]; then
|
|
# Show live output
|
|
echo "Running iperf3 test (live output):"
|
|
if docker exec "fips-${client_node}${FIPS_CI_NAME_SUFFIX:-}" timeout "$IPERF_TIMEOUT" iperf3 -c "${dest_npub}.fips" -t "$DURATION" -P "$PARALLEL"; then
|
|
PASSED=$((PASSED + 1))
|
|
else
|
|
echo "FAIL"
|
|
FAILED=$((FAILED + 1))
|
|
fi
|
|
else
|
|
# Capture and summarize output
|
|
echo -n "Running iperf3 test... "
|
|
local output
|
|
if output=$(docker exec "fips-${client_node}${FIPS_CI_NAME_SUFFIX:-}" timeout "$IPERF_TIMEOUT" iperf3 -c "${dest_npub}.fips" -t "$DURATION" -P "$PARALLEL" 2>&1); then
|
|
# Check if we got valid results
|
|
if echo "$output" | grep -q "sender"; then
|
|
# Extract and display results (get SUM line for aggregate bandwidth)
|
|
local bandwidth=$(echo "$output" | grep "\[SUM\].*sender" | tail -1 | awk '{for(i=1;i<=NF;i++) if($i ~ /bits\/sec/) {print $(i-1), $i; exit}}')
|
|
echo "OK"
|
|
echo "Bandwidth: $bandwidth"
|
|
PASSED=$((PASSED + 1))
|
|
else
|
|
echo "FAIL (no bandwidth data)"
|
|
echo "Output: $output"
|
|
FAILED=$((FAILED + 1))
|
|
fi
|
|
else
|
|
echo "FAIL"
|
|
echo "Error output:"
|
|
echo "$output" | head -10
|
|
FAILED=$((FAILED + 1))
|
|
fi
|
|
fi
|
|
}
|
|
|
|
echo "=== FIPS iperf3 Bandwidth Test ($PROFILE topology) ==="
|
|
echo ""
|
|
|
|
# Print topology so the operator can see the configured routing
|
|
# context. The bench measures iperf3 throughput between the named
|
|
# nodes — labels DO NOT encode hop count, since peer discovery
|
|
# converges every same-subnet pair onto a direct UDP path within a
|
|
# few ticks regardless of the static `peers:` list.
|
|
if [ "$PROFILE" = "mesh" ]; then
|
|
echo "Topology (static \`peers:\` from mesh.yaml):"
|
|
echo " A peers with: D, E"
|
|
echo " B peers with: C"
|
|
echo " C peers with: B, D, E"
|
|
echo " D peers with: A, C, E"
|
|
echo " E peers with: A, C, D"
|
|
echo " (Same docker-bridge subnet — discovery converges every"
|
|
echo " pair onto a direct UDP path; static \`peers:\` only seeds"
|
|
echo " the initial mesh, not the steady-state routing.)"
|
|
elif [ "$PROFILE" = "chain" ]; then
|
|
echo "Topology (static chain): A — B — C — D — E"
|
|
echo " (Same docker-bridge subnet — see mesh note above.)"
|
|
fi
|
|
echo ""
|
|
|
|
# Wait for nodes to converge
|
|
echo "Waiting ${SETTLE_SECONDS}s for mesh convergence..."
|
|
sleep "$SETTLE_SECONDS"
|
|
|
|
if [ "$PROFILE" = "mesh" ]; then
|
|
echo ""
|
|
echo "Testing mesh topology paths:"
|
|
iperf_test node-d node-a "$NPUB_D" "A→D"
|
|
iperf_test node-e node-a "$NPUB_E" "A→E"
|
|
iperf_test node-b node-a "$NPUB_B" "A→B"
|
|
iperf_test node-c node-a "$NPUB_C" "A→C"
|
|
iperf_test node-a node-e "$NPUB_A" "E→A"
|
|
|
|
elif [ "$PROFILE" = "chain" ]; then
|
|
echo ""
|
|
echo "Testing chain topology paths:"
|
|
iperf_test node-b node-a "$NPUB_B" "A→B"
|
|
iperf_test node-c node-a "$NPUB_C" "A→C"
|
|
iperf_test node-d node-a "$NPUB_D" "A→D"
|
|
iperf_test node-e node-a "$NPUB_E" "A→E"
|
|
iperf_test node-a node-e "$NPUB_A" "E→A"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Results: $PASSED passed, $FAILED failed ==="
|
|
[ "$FAILED" -eq 0 ] && exit 0 || exit 1
|