169 lines
6.7 KiB
Bash
169 lines
6.7 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# =============================================================================
|
||
|
|
# test-caddyfile-routing.sh — Unit test for Caddyfile routing block shape
|
||
|
|
#
|
||
|
|
# Verifies that the edge.hcl Nomad job template contains correctly configured
|
||
|
|
# routing blocks for all subpaths:
|
||
|
|
# - /forge/ — Forgejo subpath
|
||
|
|
# - /ci/ — Woodpecker subpath
|
||
|
|
# - /staging/ — Staging subpath
|
||
|
|
# - /chat/ — Chat subpath with forward_auth
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# test-caddyfile-routing.sh [--template PATH]
|
||
|
|
#
|
||
|
|
# Environment variables:
|
||
|
|
# EDGE_TEMPLATE — Path to edge.hcl template (default: nomad/jobs/edge.hcl)
|
||
|
|
#
|
||
|
|
# Exit codes:
|
||
|
|
# 0 — All checks passed
|
||
|
|
# 1 — One or more checks failed
|
||
|
|
# =============================================================================
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
# Script directory for relative paths
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
PROJECT_ROOT="${SCRIPT_DIR}/.."
|
||
|
|
|
||
|
|
# Configuration
|
||
|
|
EDGE_TEMPLATE="${EDGE_TEMPLATE:-${PROJECT_ROOT}/nomad/jobs/edge.hcl}"
|
||
|
|
|
||
|
|
# Track test status
|
||
|
|
FAILED=0
|
||
|
|
PASSED=0
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Logging helpers
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
log_info() {
|
||
|
|
echo "[INFO] $*"
|
||
|
|
}
|
||
|
|
|
||
|
|
log_pass() {
|
||
|
|
echo "[PASS] $*"
|
||
|
|
((PASSED++)) || true
|
||
|
|
}
|
||
|
|
|
||
|
|
log_fail() {
|
||
|
|
echo "[FAIL] $*"
|
||
|
|
((FAILED++)) || true
|
||
|
|
}
|
||
|
|
|
||
|
|
log_section() {
|
||
|
|
echo ""
|
||
|
|
echo "=== $* ==="
|
||
|
|
echo ""
|
||
|
|
}
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Test helpers
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
# Extract the Caddyfile template from edge.hcl
|
||
|
|
# The template is embedded in a Nomad template stanza with <<EOT heredoc
|
||
|
|
extract_caddyfile() {
|
||
|
|
local template_file="$1"
|
||
|
|
# Extract content between "data = <<" and "EOT" markers
|
||
|
|
# This handles the Nomad template heredoc syntax
|
||
|
|
sed -n '/data[[:space:]]*=[[:space:]]*<<[Ee][Oo][Tt]/,/^EOT$/p' "$template_file" | \
|
||
|
|
sed '1s/.*/# Caddyfile extracted from Nomad template/; $d'
|
||
|
|
}
|
||
|
|
|
||
|
|
# Check that a pattern exists in the Caddyfile
|
||
|
|
check_pattern() {
|
||
|
|
local pattern="$1"
|
||
|
|
local description="$2"
|
||
|
|
local caddyfile="$3"
|
||
|
|
|
||
|
|
if echo "$caddyfile" | grep -q "$pattern"; then
|
||
|
|
log_pass "$description"
|
||
|
|
return 0
|
||
|
|
else
|
||
|
|
log_fail "$description"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Main test suite
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
main() {
|
||
|
|
log_section "Caddyfile Routing Block Unit Test"
|
||
|
|
log_info "Template file: $EDGE_TEMPLATE"
|
||
|
|
|
||
|
|
if [ ! -f "$EDGE_TEMPLATE" ]; then
|
||
|
|
log_fail "Template file not found: $EDGE_TEMPLATE"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Extract the Caddyfile template
|
||
|
|
CADDYFILE=$(extract_caddyfile "$EDGE_TEMPLATE")
|
||
|
|
|
||
|
|
if [ -z "$CADDYFILE" ]; then
|
||
|
|
log_fail "Could not extract Caddyfile template from $EDGE_TEMPLATE"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
log_info "Caddyfile template extracted successfully"
|
||
|
|
|
||
|
|
# ─── Test 1: Forgejo subpath ────────────────────────────────────────────
|
||
|
|
log_section "Test 1: Forgejo subpath (/forge/)"
|
||
|
|
|
||
|
|
check_pattern "handle /forge/\*" "Forgejo handle block" "$CADDYFILE"
|
||
|
|
check_pattern "reverse_proxy 127.0.0.1:3000" "Forgejo reverse_proxy (port 3000)" "$CADDYFILE"
|
||
|
|
|
||
|
|
# ─── Test 2: Woodpecker subpath ─────────────────────────────────────────
|
||
|
|
log_section "Test 2: Woodpecker subpath (/ci/)"
|
||
|
|
|
||
|
|
check_pattern "handle /ci/\*" "Woodpecker handle block" "$CADDYFILE"
|
||
|
|
check_pattern "reverse_proxy 127.0.0.1:8000" "Woodpecker reverse_proxy (port 8000)" "$CADDYFILE"
|
||
|
|
|
||
|
|
# ─── Test 3: Staging subpath ────────────────────────────────────────────
|
||
|
|
log_section "Test 3: Staging subpath (/staging/)"
|
||
|
|
|
||
|
|
check_pattern "handle /staging/\*" "Staging handle block" "$CADDYFILE"
|
||
|
|
# Staging uses Nomad service discovery, so check for the template syntax
|
||
|
|
check_pattern "nomadService" "Staging Nomad service discovery" "$CADDYFILE"
|
||
|
|
|
||
|
|
# ─── Test 4: Chat subpath ───────────────────────────────────────────────
|
||
|
|
log_section "Test 4: Chat subpath (/chat/)"
|
||
|
|
|
||
|
|
check_pattern "handle /chat/login" "Chat login handle block" "$CADDYFILE"
|
||
|
|
check_pattern "handle /chat/oauth/callback" "Chat OAuth callback handle block" "$CADDYFILE"
|
||
|
|
check_pattern "handle /chat/\*" "Chat catch-all handle block" "$CADDYFILE"
|
||
|
|
check_pattern "reverse_proxy 127.0.0.1:8080" "Chat reverse_proxy (port 8080)" "$CADDYFILE"
|
||
|
|
|
||
|
|
# ─── Test 5: Forward auth for chat ──────────────────────────────────────
|
||
|
|
log_section "Test 5: Forward auth configuration"
|
||
|
|
|
||
|
|
# Check that forward_auth block exists for /chat/*
|
||
|
|
if echo "$CADDYFILE" | grep -A10 "handle /chat/\*" | grep -q "forward_auth"; then
|
||
|
|
log_pass "forward_auth block found for /chat/*"
|
||
|
|
else
|
||
|
|
log_fail "forward_auth block missing for /chat/*"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# ─── Test 6: Root redirect ──────────────────────────────────────────────
|
||
|
|
log_section "Test 6: Root redirect"
|
||
|
|
|
||
|
|
check_pattern "redir /forge/ 302" "Root redirect to /forge/" "$CADDYFILE"
|
||
|
|
|
||
|
|
# ─── Summary ────────────────────────────────────────────────────────────
|
||
|
|
log_section "Test Summary"
|
||
|
|
log_info "Passed: $PASSED"
|
||
|
|
log_info "Failed: $FAILED"
|
||
|
|
|
||
|
|
if [ $FAILED -gt 0 ]; then
|
||
|
|
log_section "TEST FAILED"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
log_section "TEST PASSED"
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
# Run main
|
||
|
|
main "$@"
|