Files
quicproquo/scripts/chat-test.sh
Christian Nennemann 2e081ead8e chore: rename quicproquo → quicprochat in docs, Docker, CI, and packaging
Rename all project references from quicproquo/qpq to quicprochat/qpc
across documentation, Docker configuration, CI workflows, packaging
scripts, operational configs, and build tooling.

- Docker: crate paths, binary names, user/group, data dirs, env vars
- CI: workflow crate references, binary names, artifact names
- Docs: all markdown files under docs/, SDK READMEs, book.toml
- Packaging: OpenWrt Makefile, init script, UCI config (file renames)
- Scripts: justfile, dev-shell, screenshot, cross-compile, ai_team
- Operations: Prometheus config, alert rules, Grafana dashboard
- Config: .env.example (QPQ_* → QPC_*), CODEOWNERS paths
- Top-level: README, CONTRIBUTING, ROADMAP, CLAUDE.md
2026-03-21 19:14:06 +01:00

163 lines
6.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# ── Interactive Chat Test ─────────────────────────────────────────────────────
#
# Spins up a server + two client containers (Alice & Bob), sets up an MLS
# group, and opens a tmux session with side-by-side interactive chat panes.
#
# Usage:
# ./scripts/chat-test.sh
#
# Requirements: docker (or podman + podman-compose), tmux
# Exit: Ctrl+D in both panes, or: tmux kill-session -t qpc-chat
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
COMPOSE_FILE="$PROJECT_ROOT/docker/docker-compose.chat-test.yml"
# ── Colors ────────────────────────────────────────────────────────────────────
GREEN='\033[0;32m'
CYAN='\033[0;36m'
RED='\033[0;31m'
NC='\033[0m'
step() { echo -e "${GREEN}==> $1${NC}"; }
info() { echo -e " ${CYAN}$1${NC}"; }
error() { echo -e "${RED}ERROR: $1${NC}" >&2; }
# ── Preflight checks ─────────────────────────────────────────────────────────
# Prefer docker; fall back to podman.
if command -v docker &>/dev/null; then
if ! docker compose version &>/dev/null; then
error "docker compose (v2 plugin) is required."
echo " See: https://docs.docker.com/compose/install/"
exit 1
fi
COMPOSE_BIN="docker compose"
elif command -v podman &>/dev/null; then
if ! command -v podman-compose &>/dev/null; then
error "podman-compose is required when using podman."
echo " pip install podman-compose"
exit 1
fi
COMPOSE_BIN="podman-compose"
else
error "docker or podman is required but neither is installed."
exit 1
fi
COMPOSE="$COMPOSE_BIN -f $COMPOSE_FILE -p qpc-chat-test"
if ! command -v tmux &>/dev/null; then
error "tmux is required but not installed."
echo " macOS: brew install tmux"
echo " Linux: sudo apt-get install tmux"
exit 1
fi
# ── Cleanup on exit ──────────────────────────────────────────────────────────
cleanup() {
echo ""
step "Tearing down containers..."
$COMPOSE down -v --remove-orphans 2>/dev/null || true
}
trap cleanup EXIT INT TERM
# ── Step 1: Build ─────────────────────────────────────────────────────────────
step "Building Docker image (server + client)..."
$COMPOSE build
# ── Step 2: Start services ────────────────────────────────────────────────────
step "Starting server, alice, bob..."
$COMPOSE up -d --wait
# ── Step 3: Verify server reachable via QUIC ──────────────────────────────────
step "Verifying QUIC connectivity from alice..."
$COMPOSE exec -T alice qpc health
# ── Step 4: Alice — register identity + upload KeyPackage ─────────────────────
step "Alice: register-state..."
$COMPOSE exec -T alice qpc register-state --state /chat/alice.bin
ALICE_KEY=$($COMPOSE exec -T alice qpc whoami --state /chat/alice.bin \
| grep 'identity_key' | awk '{print $3}' | tr -d '[:space:]')
info "Alice identity: ${ALICE_KEY}"
if [ -z "$ALICE_KEY" ]; then
error "Failed to extract Alice's identity key."
exit 1
fi
# ── Step 5: Bob — register identity + upload KeyPackage ───────────────────────
step "Bob: register-state..."
$COMPOSE exec -T bob qpc register-state --state /chat/bob.bin
BOB_KEY=$($COMPOSE exec -T bob qpc whoami --state /chat/bob.bin \
| grep 'identity_key' | awk '{print $3}' | tr -d '[:space:]')
info "Bob identity: ${BOB_KEY}"
if [ -z "$BOB_KEY" ]; then
error "Failed to extract Bob's identity key."
exit 1
fi
# ── Step 6: Alice creates group ───────────────────────────────────────────────
step "Alice: create-group 'docker-chat'..."
$COMPOSE exec -T alice qpc create-group \
--state /chat/alice.bin \
--group-id docker-chat
# ── Step 7: Alice invites Bob ─────────────────────────────────────────────────
step "Alice: invite Bob..."
$COMPOSE exec -T alice qpc invite \
--state /chat/alice.bin \
--peer-key "$BOB_KEY"
# ── Step 8: Bob joins ─────────────────────────────────────────────────────────
step "Bob: join group..."
$COMPOSE exec -T bob qpc join --state /chat/bob.bin
# ── Step 9: Launch tmux ──────────────────────────────────────────────────────
step "Launching interactive chat (tmux side-by-side)..."
echo ""
echo " Left pane: Alice"
echo " Right pane: Bob"
echo ""
echo " Type a message + Enter to send."
echo " Ctrl+D exits a pane."
echo " tmux kill-session -t qpc-chat to stop."
echo ""
ALICE_CMD="$COMPOSE exec alice qpc chat --state /chat/alice.bin"
BOB_CMD="$COMPOSE exec bob qpc chat --state /chat/bob.bin"
# Kill any stale tmux session with the same name.
tmux kill-session -t qpc-chat 2>/dev/null || true
# Create tmux session with Alice in the first pane, Bob in a horizontal split.
tmux new-session -d -s qpc-chat -x 200 -y 50 "$ALICE_CMD"
tmux split-window -h -t qpc-chat "$BOB_CMD"
# Label panes (tmux >= 2.6).
tmux select-pane -t qpc-chat:0.0 -T "Alice"
tmux select-pane -t qpc-chat:0.1 -T "Bob"
tmux set-option -t qpc-chat pane-border-status top 2>/dev/null || true
tmux set-option -t qpc-chat pane-border-format " #{pane_title} " 2>/dev/null || true
# Attach — blocks until the user exits tmux.
tmux attach-session -t qpc-chat
step "Chat session ended."