disinto/tests/test-caddyfile-routing.sh

168 lines
6.7 KiB
Bash
Executable file

#!/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 "$@"