OverviewFilesCommitsIssuesDocsReleasesPeers

hyperswarm-peer / integration / run_layer6.sh

153 lines · bash ref:
#!/usr/bin/env bash
# Layer 6: Full E2E — Election → Play → Migrate → Persist
# Tests: complete hyper-tps production flow with pure P2P mesh,
# host election, game RPCs, host migration, durable state.
# 3 Godot players use swarm_join (no sidecars).
set -euo pipefail
cd "$(dirname "$0")"

echo "=== Layer 6: Full E2E — Election → Play → Migrate → Persist ==="

# Cleanup
rm -f /tmp/layer6_*.txt /tmp/layer_bootstrap.txt

# Process tracking
PIDS=()
TESTNET_PID=""

cleanup() {
    for pid in "${PIDS[@]}" "$TESTNET_PID"; do
        [ -n "$pid" ] && kill "$pid" 2>/dev/null || true
        [ -n "$pid" ] && pkill -P "$pid" 2>/dev/null || true
    done
    sleep 0.5
    for pid in "${PIDS[@]}" "$TESTNET_PID"; do
        [ -n "$pid" ] && kill -9 "$pid" 2>/dev/null || true
        [ -n "$pid" ] && pkill -9 -P "$pid" 2>/dev/null || true
    done
    wait 2>/dev/null || true
    rm -f /tmp/layer6_*.txt /tmp/layer_bootstrap.txt
}
trap cleanup EXIT

# Start DHT testnet
echo "[orchestrator] starting DHT testnet..."
node layer2_testnet.js &
TESTNET_PID=$!

# Wait for bootstrap
for i in $(seq 1 30); do
    [ -f /tmp/layer_bootstrap.txt ] && break
    sleep 0.2
done
[ -f /tmp/layer_bootstrap.txt ] || { echo "FAIL: testnet timeout"; exit 1; }
echo "[orchestrator] testnet ready"

# Project dirs for each player
DIRS=(project project_b project_c)

# Copy test script to all project dirs
for dir in "${DIRS[@]}"; do
    cp layer6_player.gd "${dir}/layer6_player.gd" 2>/dev/null || true
done

# Start 3 Godot players
for i in 0 1 2; do
    echo "[orchestrator] starting player $i (${DIRS[$i]})..."
    timeout -k 10 90 godot4 --headless --path "${DIRS[$i]}" --script res://layer6_player.gd -- --player-index $i 2>&1 | sed "s/^/  [P$i] /" &
    PIDS+=($!)
    sleep 0.5
done

# ---- Wait for Phase 4 (play) ----
echo "[orchestrator] waiting for Phase 4 (play)..."
ELAPSED=0
while [ $ELAPSED -lt 40 ]; do
    ALL_P4=true
    ANY_FAIL=false
    for i in 0 1 2; do
        STATUS=$(cat /tmp/layer6_player_${i}_status.txt 2>/dev/null || echo "")
        if echo "$STATUS" | grep -q "^FAIL"; then
            ANY_FAIL=true
            echo "Player $i: $STATUS"
        fi
        if [ "$STATUS" != "PHASE4_OK" ] && [ "$STATUS" != "KILLED" ] && [ "$STATUS" != "PASS" ]; then
            ALL_P4=false
        fi
    done

    if $ANY_FAIL; then
        echo "=== Layer 6: FAILED (player failure) ==="
        for pid in "${PIDS[@]}"; do kill "$pid" 2>/dev/null || true; done
        exit 1
    fi

    if $ALL_P4; then
        echo "[orchestrator] Phase 4 complete — game RPCs exchanged"
        break
    fi

    sleep 1
    ELAPSED=$((ELAPSED + 1))
done

if [ $ELAPSED -ge 40 ]; then
    for i in 0 1 2; do
        echo "Player $i: $(cat /tmp/layer6_player_${i}_status.txt 2>/dev/null || echo 'no status')"
    done
    echo "=== Layer 6: TIMEOUT in Phase 4 ==="
    for pid in "${PIDS[@]}"; do kill "$pid" 2>/dev/null || true; done
    exit 1
fi

# ---- Phase 5: Kill the host ----
HOST_PK=$(cat /tmp/layer6_host_pk.txt 2>/dev/null || echo "")
if [ -n "$HOST_PK" ]; then
    echo "[orchestrator] killing host (pk: ${HOST_PK:0:12}...)"
    echo "die" > /tmp/layer6_kill_host.txt
    sleep 2
else
    echo "[orchestrator] could not determine host — skipping migration"
fi

# ---- Wait for Phase 6 (migration + persistence) ----
echo "[orchestrator] waiting for remaining players..."
ELAPSED=0
while [ $ELAPSED -lt 25 ]; do
    ALL_DONE=true
    for i in 0 1 2; do
        STATUS=$(cat /tmp/layer6_player_${i}_status.txt 2>/dev/null || echo "")
        if [ "$STATUS" != "PASS" ] && [ "$STATUS" != "KILLED" ] && [ "$STATUS" != "PHASE5_SKIP" ]; then
            ALL_DONE=false
        fi
    done
    if $ALL_DONE; then
        break
    fi
    sleep 1
    ELAPSED=$((ELAPSED + 1))
done

# Report
echo ""
for i in 0 1 2; do
    echo "Player $i: $(cat /tmp/layer6_player_${i}_status.txt 2>/dev/null || echo 'no status')"
done

# Check results
PASSED=true
for i in 0 1 2; do
    STATUS=$(cat /tmp/layer6_player_${i}_status.txt 2>/dev/null || echo "")
    if echo "$STATUS" | grep -q "FAIL"; then
        PASSED=false
    fi
done

if $PASSED; then
    echo "=== Layer 6: PASS ==="
    exit 0
else
    echo "=== Layer 6: FAILED ==="
    exit 1
fi