mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-04-16 13:13:08 +00:00
178 lines
5.4 KiB
Bash
Executable File
178 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# E2E test: starts the 5-node mix simulation, launches two chat clients,
|
|
# sends messages in both directions, and verifies delivery.
|
|
# Exit code 0 = all tests passed, 1 = failure.
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# Configurable timeouts (seconds)
|
|
SIM_TIMEOUT=${E2E_SIM_TIMEOUT:-900}
|
|
DISCOVERY_WAIT=${E2E_DISCOVERY_WAIT:-60}
|
|
MSG_TIMEOUT=${E2E_MSG_TIMEOUT:-120}
|
|
|
|
PASSED=0
|
|
FAILED=0
|
|
SIM_PID=""
|
|
CHAT1_PID=""
|
|
CHAT2_PID=""
|
|
SIM_LOG=$(mktemp)
|
|
CHAT1_LOG=$(mktemp)
|
|
CHAT2_LOG=$(mktemp)
|
|
PIPE1="/tmp/e2e_chat1_in_$$"
|
|
PIPE2="/tmp/e2e_chat2_in_$$"
|
|
|
|
cleanup() {
|
|
echo ""
|
|
echo "=== Cleanup ==="
|
|
exec 3>&- 2>/dev/null || true
|
|
exec 4>&- 2>/dev/null || true
|
|
[ -n "$CHAT1_PID" ] && kill "$CHAT1_PID" 2>/dev/null || true
|
|
[ -n "$CHAT2_PID" ] && kill "$CHAT2_PID" 2>/dev/null || true
|
|
if [ -n "$SIM_PID" ]; then
|
|
kill "$SIM_PID" 2>/dev/null || true
|
|
wait "$SIM_PID" 2>/dev/null || true
|
|
fi
|
|
pkill -f logos_host 2>/dev/null || true
|
|
rm -f "$PIPE1" "$PIPE2" 2>/dev/null || true
|
|
echo "Done."
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
echo "=== RLN Mix Network E2E Test ==="
|
|
echo ""
|
|
|
|
# ── Phase 1: Start simulation ──────────────────────────────────────
|
|
echo "[1/5] Starting simulation (this takes a few minutes)..."
|
|
|
|
bash "$SCRIPT_DIR/run_simulation.sh" > "$SIM_LOG" 2>&1 &
|
|
SIM_PID=$!
|
|
|
|
# Disable errexit — polling loops use grep/kill that may return non-zero
|
|
set +e
|
|
|
|
LAST_STEP=""
|
|
ELAPSED=0
|
|
while [ $ELAPSED -lt $SIM_TIMEOUT ]; do
|
|
if grep -q '\[7/7\] Simulation running!' "$SIM_LOG" 2>/dev/null; then
|
|
echo " Simulation ready."
|
|
break
|
|
fi
|
|
# Show simulation progress as new [N/7] lines appear
|
|
STEP_LINE=$(grep -F '/7]' "$SIM_LOG" 2>/dev/null | tail -1)
|
|
if [ -n "$STEP_LINE" ] && [ "$STEP_LINE" != "$LAST_STEP" ]; then
|
|
echo " $STEP_LINE"
|
|
LAST_STEP="$STEP_LINE"
|
|
fi
|
|
if ! kill -0 "$SIM_PID" 2>/dev/null; then
|
|
echo "FATAL: Simulation exited prematurely."
|
|
tail -30 "$SIM_LOG"
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
ELAPSED=$((ELAPSED + 2))
|
|
done
|
|
|
|
if ! grep -q '\[7/7\] Simulation running!' "$SIM_LOG" 2>/dev/null; then
|
|
echo "FATAL: Simulation not ready after ${SIM_TIMEOUT}s."
|
|
tail -30 "$SIM_LOG"
|
|
exit 1
|
|
fi
|
|
|
|
# ── Phase 2: Start chat clients ────────────────────────────────────
|
|
echo "[2/5] Starting chat clients..."
|
|
|
|
rm -f "$PIPE1" "$PIPE2"
|
|
mkfifo "$PIPE1" "$PIPE2"
|
|
|
|
# Open FIFOs read-write (<>) so open(2) never blocks and the write end
|
|
# stays alive as long as the FD is open — even if readers come and go.
|
|
exec 3<>"$PIPE1"
|
|
exec 4<>"$PIPE2"
|
|
|
|
# Start chat clients reading from the FIFOs.
|
|
bash "$SCRIPT_DIR/run_chat_mix.sh" < "$PIPE1" > "$CHAT1_LOG" 2>&1 &
|
|
CHAT1_PID=$!
|
|
bash "$SCRIPT_DIR/run_chat_mix1.sh" < "$PIPE2" > "$CHAT2_LOG" 2>&1 &
|
|
CHAT2_PID=$!
|
|
|
|
echo "TestAlice" >&3
|
|
echo "TestBob" >&4
|
|
echo " Clients started, nicknames sent."
|
|
|
|
# ── Phase 3: Wait for mix node discovery ───────────────────────────
|
|
echo "[3/5] Waiting for mix node discovery (up to ${DISCOVERY_WAIT}s)..."
|
|
|
|
DISC_ELAPSED=0
|
|
C1_READY=0
|
|
C2_READY=0
|
|
while [ $DISC_ELAPSED -lt $DISCOVERY_WAIT ]; do
|
|
[ $C1_READY -eq 0 ] && grep -q "ready to publish messages now" "$CHAT1_LOG" 2>/dev/null && { echo " Alice: ready"; C1_READY=1; }
|
|
[ $C2_READY -eq 0 ] && grep -q "ready to publish messages now" "$CHAT2_LOG" 2>/dev/null && { echo " Bob: ready"; C2_READY=1; }
|
|
[ $C1_READY -eq 1 ] && [ $C2_READY -eq 1 ] && break
|
|
sleep 2
|
|
DISC_ELAPSED=$((DISC_ELAPSED + 2))
|
|
done
|
|
|
|
if [ $C1_READY -eq 0 ] || [ $C2_READY -eq 0 ]; then
|
|
echo "FATAL: Chat clients not ready within ${DISCOVERY_WAIT}s."
|
|
[ $C1_READY -eq 0 ] && { echo " Alice log tail:"; tail -10 "$CHAT1_LOG"; }
|
|
[ $C2_READY -eq 0 ] && { echo " Bob log tail:"; tail -10 "$CHAT2_LOG"; }
|
|
exit 1
|
|
fi
|
|
|
|
echo " Settling filter subscriptions (20s)..."
|
|
sleep 20
|
|
|
|
# ── Phase 4: Send messages and verify delivery ─────────────────────
|
|
echo "[4/5] Sending messages and verifying delivery..."
|
|
|
|
MSG_A="e2e_alice_$(date +%s)"
|
|
MSG_B="e2e_bob_$(date +%s)"
|
|
|
|
check_delivery() {
|
|
local log_file=$1
|
|
local pattern=$2
|
|
local label=$3
|
|
local elapsed=0
|
|
while [ $elapsed -lt $MSG_TIMEOUT ]; do
|
|
if grep -q "$pattern" "$log_file" 2>/dev/null; then
|
|
echo " PASS: $label"
|
|
PASSED=$((PASSED + 1))
|
|
return 0
|
|
fi
|
|
sleep 3
|
|
elapsed=$((elapsed + 3))
|
|
done
|
|
echo " FAIL: $label (not received after ${MSG_TIMEOUT}s)"
|
|
FAILED=$((FAILED + 1))
|
|
return 0
|
|
}
|
|
|
|
echo " Sending: Alice -> '$MSG_A'"
|
|
echo "$MSG_A" >&3
|
|
|
|
echo " Sending: Bob -> '$MSG_B'"
|
|
echo "$MSG_B" >&4
|
|
|
|
echo " Waiting for delivery (up to ${MSG_TIMEOUT}s per message)..."
|
|
|
|
check_delivery "$CHAT2_LOG" "$MSG_A" "Alice -> Bob"
|
|
check_delivery "$CHAT1_LOG" "$MSG_B" "Bob -> Alice"
|
|
|
|
# ── Phase 5: Report ────────────────────────────────────────────────
|
|
echo ""
|
|
echo "[5/5] Results: $PASSED passed, $FAILED failed"
|
|
echo ""
|
|
|
|
if [ $FAILED -eq 0 ] && [ $PASSED -ge 2 ]; then
|
|
echo "E2E TEST PASSED"
|
|
exit 0
|
|
else
|
|
echo "E2E TEST FAILED"
|
|
echo " Simulation log: $SIM_LOG"
|
|
echo " Alice log: $CHAT1_LOG"
|
|
echo " Bob log: $CHAT2_LOG"
|
|
exit 1
|
|
fi
|