feat: variant testing — 6 subdomains + Caddy wildcard cert
- v1-v6.voip.manko.yoga → each maps to a WZP client variant - Caddyfile.test: wildcard *.voip.manko.yoga with CF DNS cert - scripts/test-variants.sh: --setup creates DNS + swaps Caddyfile - --teardown cleans up DNS + restores original - --check verifies all 6 respond HTTP 200 - All variants join same room for cross-variant audio testing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
42
warzone/deploy/docker/Caddyfile.test
Normal file
42
warzone/deploy/docker/Caddyfile.test
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
email admin@manko.yoga
|
||||
}
|
||||
|
||||
# Wildcard cert for all variant subdomains
|
||||
*.voip.manko.yoga {
|
||||
tls {
|
||||
dns cloudflare {$CF_API_TOKEN}
|
||||
}
|
||||
|
||||
# Route each subdomain to wzp-web with the right variant
|
||||
@v1 host v1.voip.manko.yoga
|
||||
@v2 host v2.voip.manko.yoga
|
||||
@v3 host v3.voip.manko.yoga
|
||||
@v4 host v4.voip.manko.yoga
|
||||
@v5 host v5.voip.manko.yoga
|
||||
@v6 host v6.voip.manko.yoga
|
||||
|
||||
# Rewrite root path to include variant param
|
||||
rewrite @v1 / /?variant=pure
|
||||
rewrite @v2 / /?variant=hybrid
|
||||
rewrite @v3 / /?variant=full
|
||||
rewrite @v4 / /?variant=ws
|
||||
rewrite @v5 / /?variant=ws-fec
|
||||
rewrite @v6 / /?variant=ws-full
|
||||
|
||||
# All subdomains proxy to wzp-web
|
||||
reverse_proxy wzp-web:8080
|
||||
}
|
||||
|
||||
# Main domain — featherChat server
|
||||
voip.manko.yoga {
|
||||
tls {
|
||||
dns cloudflare {$CF_API_TOKEN}
|
||||
}
|
||||
|
||||
handle_path /audio/* {
|
||||
reverse_proxy wzp-web:8080
|
||||
}
|
||||
|
||||
reverse_proxy warzone-server:7700
|
||||
}
|
||||
171
warzone/scripts/test-variants.sh
Executable file
171
warzone/scripts/test-variants.sh
Executable file
@@ -0,0 +1,171 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Test all 6 WZP web client variants with dedicated subdomains.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/test-variants.sh --setup Create DNS + switch Caddyfile
|
||||
# ./scripts/test-variants.sh --teardown Remove DNS + restore Caddyfile
|
||||
# ./scripts/test-variants.sh --urls Print all test URLs
|
||||
# ./scripts/test-variants.sh --check Verify all 6 respond
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
DOCKER_DIR="$PROJECT_DIR/deploy/docker"
|
||||
CF_TOKEN_FILE="$DOCKER_DIR/cf_api_token.txt"
|
||||
CF_ZONE="manko.yoga"
|
||||
BASE_DOMAIN="voip.manko.yoga"
|
||||
|
||||
VARIANTS=(v1 v2 v3 v4 v5 v6)
|
||||
LABELS=("pure" "hybrid" "full" "ws" "ws-fec" "ws-full")
|
||||
|
||||
get_cf_token() {
|
||||
cat "$CF_TOKEN_FILE" | tr -d '\n'
|
||||
}
|
||||
|
||||
get_zone_id() {
|
||||
curl -4 -s "https://api.cloudflare.com/client/v4/zones?name=$CF_ZONE" \
|
||||
-H "Authorization: Bearer $(get_cf_token)" | \
|
||||
python3 -c "import sys,json; print(json.load(sys.stdin)['result'][0]['id'])"
|
||||
}
|
||||
|
||||
get_my_ip() {
|
||||
curl -4 -s --connect-timeout 5 https://api.ipify.org 2>/dev/null || \
|
||||
ifconfig | grep "inet " | grep -v 127.0.0.1 | head -1 | awk '{print $2}'
|
||||
}
|
||||
|
||||
do_setup() {
|
||||
local ip zone_id cf_token
|
||||
ip=$(get_my_ip)
|
||||
cf_token=$(get_cf_token)
|
||||
zone_id=$(get_zone_id)
|
||||
|
||||
echo "Setting up variant testing"
|
||||
echo " IP: $ip"
|
||||
echo " Zone: $zone_id"
|
||||
echo ""
|
||||
|
||||
# Create A records for each subdomain
|
||||
for i in "${!VARIANTS[@]}"; do
|
||||
local sub="${VARIANTS[$i]}"
|
||||
local fqdn="${sub}.${BASE_DOMAIN}"
|
||||
local label="${LABELS[$i]}"
|
||||
|
||||
# Check existing
|
||||
local rec_id
|
||||
rec_id=$(curl -4 -s "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?name=$fqdn&type=A" \
|
||||
-H "Authorization: Bearer $cf_token" | python3 -c "import sys,json; r=json.load(sys.stdin)['result']; print(r[0]['id'] if r else '')" 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$rec_id" ]; then
|
||||
curl -4 -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$rec_id" \
|
||||
-H "Authorization: Bearer $cf_token" -H "Content-Type: application/json" \
|
||||
--data "{\"type\":\"A\",\"name\":\"$fqdn\",\"content\":\"$ip\",\"ttl\":120,\"proxied\":false}" > /dev/null
|
||||
echo " $fqdn → $ip (updated) [$label]"
|
||||
else
|
||||
curl -4 -s -X POST "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records" \
|
||||
-H "Authorization: Bearer $cf_token" -H "Content-Type: application/json" \
|
||||
--data "{\"type\":\"A\",\"name\":\"$fqdn\",\"content\":\"$ip\",\"ttl\":120,\"proxied\":false}" > /dev/null
|
||||
echo " $fqdn → $ip (created) [$label]"
|
||||
fi
|
||||
done
|
||||
|
||||
# Switch Caddyfile
|
||||
echo ""
|
||||
echo "Switching Caddyfile to test mode..."
|
||||
cp "$DOCKER_DIR/Caddyfile" "$DOCKER_DIR/Caddyfile.backup"
|
||||
cp "$DOCKER_DIR/Caddyfile.test" "$DOCKER_DIR/Caddyfile"
|
||||
|
||||
echo "Restarting Caddy..."
|
||||
cd "$DOCKER_DIR" && docker compose restart caddy
|
||||
|
||||
echo ""
|
||||
echo "=== Ready ==="
|
||||
do_urls
|
||||
}
|
||||
|
||||
do_teardown() {
|
||||
local cf_token zone_id
|
||||
cf_token=$(get_cf_token)
|
||||
zone_id=$(get_zone_id)
|
||||
|
||||
echo "Tearing down variant testing..."
|
||||
|
||||
for sub in "${VARIANTS[@]}"; do
|
||||
local fqdn="${sub}.${BASE_DOMAIN}"
|
||||
local rec_id
|
||||
rec_id=$(curl -4 -s "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?name=$fqdn&type=A" \
|
||||
-H "Authorization: Bearer $cf_token" | python3 -c "import sys,json; r=json.load(sys.stdin)['result']; print(r[0]['id'] if r else '')" 2>/dev/null || echo "")
|
||||
if [ -n "$rec_id" ]; then
|
||||
curl -4 -s -X DELETE "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$rec_id" \
|
||||
-H "Authorization: Bearer $cf_token" > /dev/null
|
||||
echo " Deleted $fqdn"
|
||||
fi
|
||||
done
|
||||
|
||||
# Restore Caddyfile
|
||||
if [ -f "$DOCKER_DIR/Caddyfile.backup" ]; then
|
||||
mv "$DOCKER_DIR/Caddyfile.backup" "$DOCKER_DIR/Caddyfile"
|
||||
echo "Restored original Caddyfile"
|
||||
cd "$DOCKER_DIR" && docker compose restart caddy
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
do_urls() {
|
||||
echo ""
|
||||
echo "Test URLs (open each in a browser tab, enter same room name):"
|
||||
echo ""
|
||||
echo " ┌────────┬──────────┬──────────────────────────────────────────┐"
|
||||
echo " │ Domain │ Variant │ URL │"
|
||||
echo " ├────────┼──────────┼──────────────────────────────────────────┤"
|
||||
for i in "${!VARIANTS[@]}"; do
|
||||
local sub="${VARIANTS[$i]}"
|
||||
local label="${LABELS[$i]}"
|
||||
printf " │ %-6s │ %-8s │ https://%s.%s/test-room │\n" "$sub" "$label" "$sub" "$BASE_DOMAIN"
|
||||
done
|
||||
echo " └────────┴──────────┴──────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo "All variants join the same room — test cross-variant audio."
|
||||
echo "featherChat: https://$BASE_DOMAIN (call via /call command)"
|
||||
}
|
||||
|
||||
do_check() {
|
||||
echo "Checking all variant endpoints..."
|
||||
local pass=0 fail=0
|
||||
|
||||
for i in "${!VARIANTS[@]}"; do
|
||||
local sub="${VARIANTS[$i]}"
|
||||
local label="${LABELS[$i]}"
|
||||
local url="https://${sub}.${BASE_DOMAIN}/"
|
||||
local status
|
||||
status=$(curl -4 -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "$url" 2>/dev/null || echo "000")
|
||||
if [ "$status" = "200" ]; then
|
||||
echo " OK $sub ($label): $status"
|
||||
pass=$((pass + 1))
|
||||
else
|
||||
echo " FAIL $sub ($label): $status"
|
||||
fail=$((fail + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Results: $pass passed, $fail failed"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
--setup) do_setup ;;
|
||||
--teardown) do_teardown ;;
|
||||
--urls) do_urls ;;
|
||||
--check) do_check ;;
|
||||
*)
|
||||
echo "Test all 6 WZP web client variants"
|
||||
echo ""
|
||||
echo "Usage: $0 <command>"
|
||||
echo ""
|
||||
echo " --setup Create DNS records + switch Caddyfile"
|
||||
echo " --teardown Remove DNS records + restore Caddyfile"
|
||||
echo " --urls Print test URLs"
|
||||
echo " --check Verify all 6 respond with HTTP 200"
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user