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:
Siavash Sameni
2026-03-30 15:01:38 +04:00
parent da3cdd7234
commit 561f2d6978
2 changed files with 213 additions and 0 deletions

View 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
View 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