#!/usr/bin/env bash # ============================================================================= # test-endpoints.sh # Tests all Webzine endpoints and reports which ones exceed the threshold. # # Usage: # ./scripts/test-endpoints.sh [BASE_URL] [MAX_MS] # # Examples: # ./scripts/test-endpoints.sh # defaults: localhost:5038, 1000ms # ./scripts/test-endpoints.sh http://localhost:5038 500 # ============================================================================= set -euo pipefail BASE_URL="${1:-http://localhost:5038}" MAX_MS="${2:-1000}" REPORT_FILE="/tmp/webzine_endpoint_report.txt" FAILED=0 TOTAL=0 # ── Colours ────────────────────────────────────────────────────────────────── RED='\033[0;31m' YELLOW='\033[1;33m' GREEN='\033[0;32m' CYAN='\033[0;36m' BOLD='\033[1m' RESET='\033[0m' # ── Helpers ────────────────────────────────────────────────────────────────── log() { echo -e "$*"; } pass() { log "${GREEN}[PASS]${RESET} $*"; } fail() { log "${RED}[FAIL]${RESET} $*"; FAILED=$((FAILED + 1)); } slow() { log "${YELLOW}[SLOW]${RESET} $*"; FAILED=$((FAILED + 1)); } info() { log "${CYAN}$*${RESET}"; } # ── check_endpoint ──────────────────────────────────────────────────────────── # Arguments: # $1 HTTP method (GET | POST) # $2 URL (absolute) # $3 Label (human-readable) # $4 Body data (optional, for POST) # $5 Content-Type (optional, default: application/x-www-form-urlencoded) # ───────────────────────────────────────────────────────────────────────────── check_endpoint() { local METHOD="${1:-GET}" local URL="$2" local LABEL="$3" local BODY="${4:-}" local CONTENT_TYPE="${5:-application/x-www-form-urlencoded}" TOTAL=$((TOTAL + 1)) if [ "$METHOD" = "POST" ] && [ -n "$BODY" ]; then RESPONSE=$(curl -s -o /dev/null \ -w "%{http_code}|%{time_total}" \ -X POST \ -H "Content-Type: $CONTENT_TYPE" \ -d "$BODY" \ --max-time 10 \ "$URL" 2>&1) || RESPONSE="000|9.999" else RESPONSE=$(curl -s -o /dev/null \ -w "%{http_code}|%{time_total}" \ -X GET \ --max-time 10 \ --location \ "$URL" 2>&1) || RESPONSE="000|9.999" fi HTTP_CODE=$(echo "$RESPONSE" | cut -d'|' -f1) TIME_TOTAL=$(echo "$RESPONSE" | cut -d'|' -f2) # Convert to integer milliseconds — awk is locale-safe, no bc/printf decimal issues TIME_MS=$(awk "BEGIN {printf \"%.0f\", $TIME_TOTAL * 1000}") # Evaluate result if [ "${HTTP_CODE:-0}" -ge 500 ] 2>/dev/null; then slow "$LABEL → HTTP $HTTP_CODE (${TIME_MS}ms)" echo "[FAIL] $LABEL → HTTP $HTTP_CODE (${TIME_MS}ms)" >> "$REPORT_FILE" elif [ "${TIME_MS:-99999}" -gt "$MAX_MS" ] 2>/dev/null; then slow "$LABEL → ${TIME_MS}ms exceeds ${MAX_MS}ms threshold" echo "[SLOW] $LABEL → ${TIME_MS}ms (limit: ${MAX_MS}ms)" >> "$REPORT_FILE" else pass "$LABEL → ${TIME_MS}ms" echo "[OK] $LABEL → ${TIME_MS}ms" >> "$REPORT_FILE" fi } # ============================================================================= # MAIN # ============================================================================= # Initialise report > "$REPORT_FILE" cat >> "$REPORT_FILE" </dev/null || echo "$STYLE") check_endpoint GET "$BASE_URL/titre/style/$ENCODED" "GET /titre/style/$STYLE" done log "" info "── Artiste ───────────────────────────────────────────────" ARTISTES=("fatal-bazooka" "daft-punk" "justice" "kraftwerk") for ARTISTE in "${ARTISTES[@]}"; do check_endpoint GET "$BASE_URL/artiste/$ARTISTE" "GET /artiste/$ARTISTE" done log "" info "── Recherche (POST) ──────────────────────────────────────" MOTS=("rock" "jazz" "pop" "metal") for MOT in "${MOTS[@]}"; do check_endpoint POST "$BASE_URL/recherche" \ "POST /recherche (mot=$MOT)" \ "mot=$MOT" done log "" # ── ADMINISTRATION SECTION ──────────────────────────────────────────────────── info "── Administration – Dashboard ────────────────────────────" check_endpoint GET "$BASE_URL/Administration/Dashboard" "GET /Administration/Dashboard" log "" info "── Administration – Artiste ──────────────────────────────" check_endpoint GET "$BASE_URL/Administration/Artiste" "GET /Administration/Artiste (Index)" check_endpoint GET "$BASE_URL/Administration/Artiste/Create" "GET /Administration/Artiste/Create" check_endpoint GET "$BASE_URL/Administration/Artiste/Edit/1" "GET /Administration/Artiste/Edit/1" check_endpoint GET "$BASE_URL/Administration/Artiste/Delete/1" "GET /Administration/Artiste/Delete/1" log "" info "── Administration – Commentaire ──────────────────────────" check_endpoint GET "$BASE_URL/Administration/Commentaire" "GET /Administration/Commentaire (Index)" check_endpoint GET "$BASE_URL/Administration/Commentaire/Delete/1" \ "GET /Administration/Commentaire/Delete/1" log "" info "── Administration – Style ────────────────────────────────" check_endpoint GET "$BASE_URL/Administration/Style" "GET /Administration/Style (Index)" check_endpoint GET "$BASE_URL/Administration/Style/Create" "GET /Administration/Style/Create" check_endpoint GET "$BASE_URL/Administration/Style/Edit/1" "GET /Administration/Style/Edit/1" check_endpoint GET "$BASE_URL/Administration/Style/Delete/1" "GET /Administration/Style/Delete/1" log "" info "── Administration – Titre ────────────────────────────────" check_endpoint GET "$BASE_URL/Administration/Titre" "GET /Administration/Titre (Index)" check_endpoint GET "$BASE_URL/Administration/Titre/Create" "GET /Administration/Titre/Create" check_endpoint GET "$BASE_URL/Administration/Titre/Edit/1" "GET /Administration/Titre/Edit/1" check_endpoint GET "$BASE_URL/Administration/Titre/Delete/1" "GET /Administration/Titre/Delete/1" # ── SUMMARY ─────────────────────────────────────────────────────────────────── PASSED=$((TOTAL - FAILED)) log "" info "╔══════════════════════════════════════════════════════════╗" info "║ Results ║" info "╚══════════════════════════════════════════════════════════╝" log " Total : ${TOTAL}" log " ${GREEN}Passed${RESET} : ${PASSED}" if [ "$FAILED" -gt 0 ]; then log " ${RED}Failed${RESET} : ${FAILED}" log "" log "${RED}${BOLD}❌ FAILED ENDPOINTS:${RESET}" grep -E "^\[(FAIL|SLOW)\]" "$REPORT_FILE" | while IFS= read -r line; do log " ${RED}→${RESET} $line" done log "" log "${RED}PR should be rejected. Fix the endpoints above.${RESET}" else log " ${GREEN}Failed${RESET} : 0" log "" log "${GREEN}${BOLD}✅ All endpoints are within the ${MAX_MS}ms threshold.${RESET}" fi log "" log "Full report saved to: ${REPORT_FILE}" log "" # Write summary to report cat >> "$REPORT_FILE" <