236 lines
9.5 KiB
Bash
236 lines
9.5 KiB
Bash
#!/bin/bash
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
# WalkGuide — k6 Test Runner
|
|
# Jalankan semua k6 scenarios secara berurutan atau individual.
|
|
#
|
|
# Usage:
|
|
# chmod +x run-all-tests.sh
|
|
# ./run-all-tests.sh [mode] [BASE_URL]
|
|
#
|
|
# Modes:
|
|
# smoke — 10 VUs, 1 menit (quick sanity check)
|
|
# load — 50 VUs, 5 menit (normal production load, WAJIB untuk exam)
|
|
# stress — 100 VUs, 10 menit (breaking point)
|
|
# spike — 0→200 VUs sudden spike
|
|
# all — jalankan smoke → load → stress → spike berurutan
|
|
# auth — hanya auth-flow.js
|
|
# pairing — hanya pairing-flow.js
|
|
# location — hanya location-update.js
|
|
# obstacle — hanya obstacle-logging.js
|
|
# sos — hanya sos-flow.js
|
|
# notif — hanya notification-send.js
|
|
# timeline — hanya timeline-query.js
|
|
#
|
|
# Contoh:
|
|
# ./run-all-tests.sh load http://202.46.28.160:8080
|
|
# ./run-all-tests.sh smoke
|
|
# ./run-all-tests.sh all http://202.46.28.160:8080
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
set -e
|
|
|
|
# ── Config ────────────────────────────────────────────────────────────────────
|
|
MODE="${1:-load}"
|
|
BASE_URL="${2:-http://202.46.28.160:8080}"
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
RESULTS_DIR="${SCRIPT_DIR}/k6-results"
|
|
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
|
|
|
# ── Colors ────────────────────────────────────────────────────────────────────
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
BOLD='\033[1m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# ── Helpers ───────────────────────────────────────────────────────────────────
|
|
log() { echo -e "${CYAN}[$(date +%H:%M:%S)]${NC} $1"; }
|
|
ok() { echo -e "${GREEN}[✅ OK]${NC} $1"; }
|
|
warn() { echo -e "${YELLOW}[⚠️ WARN]${NC} $1"; }
|
|
err() { echo -e "${RED}[❌ ERR]${NC} $1"; }
|
|
hr() { echo -e "${BLUE}═══════════════════════════════════════════════════════${NC}"; }
|
|
|
|
# ── Pre-flight checks ─────────────────────────────────────────────────────────
|
|
hr
|
|
echo -e "${BOLD} 🦺 WalkGuide — k6 Load Test Runner${NC}"
|
|
echo -e " Mode: ${YELLOW}${MODE}${NC} | Backend: ${YELLOW}${BASE_URL}${NC}"
|
|
hr
|
|
|
|
# Check k6 installed
|
|
if ! command -v k6 &> /dev/null; then
|
|
err "k6 not installed!"
|
|
echo "Install: https://k6.io/docs/getting-started/installation/"
|
|
echo "Ubuntu: sudo apt-get install k6"
|
|
echo "Mac: brew install k6"
|
|
echo "Docker: docker run grafana/k6 run ..."
|
|
exit 1
|
|
fi
|
|
|
|
K6_VERSION=$(k6 version 2>&1 | head -1)
|
|
ok "k6 found: $K6_VERSION"
|
|
|
|
# Check Node.js (for result parsing)
|
|
if command -v node &> /dev/null; then
|
|
ok "Node.js: $(node --version)"
|
|
else
|
|
warn "Node.js not found — skipping HTML report generation"
|
|
fi
|
|
|
|
# Create results dir
|
|
mkdir -p "$RESULTS_DIR"
|
|
ok "Results dir: $RESULTS_DIR"
|
|
|
|
# ── Backend reachability check ────────────────────────────────────────────────
|
|
log "Checking backend reachability..."
|
|
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${BASE_URL}/api/v1/auth/ping" --max-time 10 2>/dev/null || echo "000")
|
|
|
|
if [ "$HTTP_STATUS" = "200" ]; then
|
|
ok "Backend reachable (HTTP $HTTP_STATUS)"
|
|
elif [ "$HTTP_STATUS" = "000" ]; then
|
|
warn "Backend not reachable or timeout. Continuing anyway (tests will fail gracefully)."
|
|
else
|
|
warn "Backend returned HTTP $HTTP_STATUS. Continuing..."
|
|
fi
|
|
|
|
# ── k6 run helper ─────────────────────────────────────────────────────────────
|
|
run_k6() {
|
|
local scenario_file="$1"
|
|
local scenario_name="$2"
|
|
local extra_args="${3:-}"
|
|
|
|
local output_json="${RESULTS_DIR}/${scenario_name}_${TIMESTAMP}.ndjson"
|
|
local summary_json="${RESULTS_DIR}/${scenario_name}_summary_${TIMESTAMP}.json"
|
|
|
|
log "Running scenario: ${BOLD}${scenario_name}${NC}"
|
|
log "Script: ${scenario_file}"
|
|
|
|
local k6_cmd="k6 run \
|
|
--out json=${output_json} \
|
|
-e BASE_URL=${BASE_URL} \
|
|
--summary-export=${summary_json} \
|
|
--no-color \
|
|
${extra_args} \
|
|
${SCRIPT_DIR}/scenarios/${scenario_file}"
|
|
|
|
echo "Command: $k6_cmd"
|
|
hr
|
|
|
|
if eval "$k6_cmd"; then
|
|
ok "Scenario ${scenario_name} completed successfully"
|
|
else
|
|
warn "Scenario ${scenario_name} completed with threshold violations (check results)"
|
|
fi
|
|
|
|
# Parse results if Node.js available
|
|
if command -v node &> /dev/null && [ -f "$output_json" ]; then
|
|
log "Parsing results..."
|
|
local parsed_json="${RESULTS_DIR}/${scenario_name}_parsed_${TIMESTAMP}.json"
|
|
local html_report="${RESULTS_DIR}/${scenario_name}_report_${TIMESTAMP}.html"
|
|
|
|
node "${SCRIPT_DIR}/utils/result-parser.js" "$output_json" "$parsed_json" 2>/dev/null || true
|
|
node "${SCRIPT_DIR}/utils/html-reporter.js" "$parsed_json" "$html_report" 2>/dev/null || true
|
|
|
|
if [ -f "$html_report" ]; then
|
|
ok "HTML report: $html_report"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
}
|
|
|
|
# ── Stage-specific k6 args ────────────────────────────────────────────────────
|
|
SMOKE_ARGS="--stage 30s:3 --stage 60s:10 --stage 30s:0"
|
|
# Note: --stage shorthand diganti inline di script JSON
|
|
|
|
# ── Test execution ─────────────────────────────────────────────────────────────
|
|
case "$MODE" in
|
|
|
|
smoke)
|
|
log "=== SMOKE TEST (10 VUs, 1 min) ==="
|
|
run_k6 "auth-flow.js" "smoke_auth" "--vus 3 --duration 60s"
|
|
run_k6 "location-update.js" "smoke_location" "--vus 3 --duration 60s"
|
|
run_k6 "sos-flow.js" "smoke_sos" "--vus 2 --duration 60s"
|
|
;;
|
|
|
|
load)
|
|
log "=== LOAD TEST (50+ VUs, 5 min) — EXAM REQUIRED ==="
|
|
run_k6 "auth-flow.js" "load_auth"
|
|
run_k6 "pairing-flow.js" "load_pairing"
|
|
run_k6 "location-update.js" "load_location"
|
|
run_k6 "obstacle-logging.js" "load_obstacle"
|
|
run_k6 "sos-flow.js" "load_sos"
|
|
run_k6 "notification-send.js" "load_notif"
|
|
run_k6 "timeline-query.js" "load_timeline"
|
|
;;
|
|
|
|
stress)
|
|
log "=== STRESS TEST (100 VUs, 10 min) ==="
|
|
run_k6 "location-update.js" "stress_location"
|
|
run_k6 "obstacle-logging.js" "stress_obstacle"
|
|
run_k6 "notification-send.js" "stress_notif"
|
|
run_k6 "timeline-query.js" "stress_timeline"
|
|
;;
|
|
|
|
spike)
|
|
log "=== SPIKE TEST (0→200 VUs sudden) ==="
|
|
run_k6 "location-update.js" "spike_location"
|
|
run_k6 "obstacle-logging.js" "spike_obstacle"
|
|
;;
|
|
|
|
all)
|
|
log "=== FULL TEST SUITE (smoke → load → stress → spike) ==="
|
|
warn "Estimated total time: 30-45 minutes"
|
|
read -p "Continue? [y/N] " confirm
|
|
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
|
|
echo "Aborted."; exit 0
|
|
fi
|
|
|
|
# Smoke
|
|
log "--- Phase 1: Smoke Test ---"
|
|
run_k6 "auth-flow.js" "fullsuite_smoke_auth" "--vus 3 --duration 60s"
|
|
run_k6 "location-update.js" "fullsuite_smoke_location" "--vus 3 --duration 60s"
|
|
|
|
# Load
|
|
log "--- Phase 2: Load Test ---"
|
|
run_k6 "auth-flow.js" "fullsuite_load_auth"
|
|
run_k6 "location-update.js" "fullsuite_load_location"
|
|
run_k6 "obstacle-logging.js" "fullsuite_load_obstacle"
|
|
run_k6 "sos-flow.js" "fullsuite_load_sos"
|
|
run_k6 "notification-send.js" "fullsuite_load_notif"
|
|
run_k6 "timeline-query.js" "fullsuite_load_timeline"
|
|
|
|
# Stress
|
|
log "--- Phase 3: Stress Test ---"
|
|
run_k6 "location-update.js" "fullsuite_stress_location"
|
|
|
|
# Spike
|
|
log "--- Phase 4: Spike Test ---"
|
|
run_k6 "location-update.js" "fullsuite_spike_location"
|
|
;;
|
|
|
|
# Individual scenarios
|
|
auth) run_k6 "auth-flow.js" "individual_auth" ;;
|
|
pairing) run_k6 "pairing-flow.js" "individual_pairing" ;;
|
|
location) run_k6 "location-update.js" "individual_location" ;;
|
|
obstacle) run_k6 "obstacle-logging.js" "individual_obstacle" ;;
|
|
sos) run_k6 "sos-flow.js" "individual_sos" ;;
|
|
notif) run_k6 "notification-send.js" "individual_notif" ;;
|
|
timeline) run_k6 "timeline-query.js" "individual_timeline" ;;
|
|
|
|
*)
|
|
err "Unknown mode: $MODE"
|
|
echo "Valid modes: smoke | load | stress | spike | all | auth | pairing | location | obstacle | sos | notif | timeline"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# ── Final summary ─────────────────────────────────────────────────────────────
|
|
hr
|
|
ok "All k6 tests finished!"
|
|
log "Results saved to: $RESULTS_DIR"
|
|
echo ""
|
|
echo "Files generated:"
|
|
ls -lh "$RESULTS_DIR"/*.{json,html} 2>/dev/null || echo " (no files found)"
|
|
hr |