#!/bin/bash set -euo pipefail # Deployment Testing Script # Tests all deployment components and verifies functionality SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' PASSED=0 FAILED=0 SKIPPED=0 log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[PASS]${NC} $1" ((PASSED++)) } log_error() { echo -e "${RED}[FAIL]${NC} $1" ((FAILED++)) } log_skip() { echo -e "${YELLOW}[SKIP]${NC} $1" ((SKIPPED++)) } test_command() { local name=$1 local command=$2 log_info "Testing: $name" if eval "$command" &>/dev/null; then log_success "$name" return 0 else log_error "$name" return 1 fi } test_http() { local name=$1 local url=$2 local expected_status=${3:-200} log_info "Testing: $name" status=$(curl -s -o /dev/null -w "%{http_code}" "$url" || echo "000") if [ "$status" = "$expected_status" ]; then log_success "$name" return 0 else log_error "$name (got status $status, expected $expected_status)" return 1 fi } test_graphql() { local name=$1 local query=$2 local url=${3:-https://api.sankofa.nexus/graphql} local token=${4:-} log_info "Testing: $name" headers=(-H "Content-Type: application/json") if [ -n "$token" ]; then headers+=(-H "Authorization: Bearer $token") fi response=$(curl -s "${headers[@]}" -d "{\"query\":\"$query\"}" "$url" || echo "{}") if echo "$response" | jq -e '.errors' > /dev/null 2>&1; then log_error "$name (GraphQL errors)" return 1 elif echo "$response" | jq -e '.data' > /dev/null 2>&1; then log_success "$name" return 0 else log_error "$name (invalid response)" return 1 fi } # Main test suite main() { log_info "Starting deployment tests..." echo "" # Prerequisites log_info "=== Prerequisites ===" test_command "kubectl available" "kubectl version --client" test_command "helm available" "helm version" test_command "jq available" "jq --version" test_command "curl available" "curl --version" echo "" # Kubernetes Cluster log_info "=== Kubernetes Cluster ===" test_command "Cluster accessible" "kubectl cluster-info" test_command "API server reachable" "kubectl get nodes" echo "" # Namespaces log_info "=== Namespaces ===" test_command "API namespace exists" "kubectl get namespace api" test_command "Portal namespace exists" "kubectl get namespace portal" test_command "Keycloak namespace exists" "kubectl get namespace keycloak" test_command "Monitoring namespace exists" "kubectl get namespace monitoring" echo "" # API Deployment log_info "=== API Deployment ===" test_command "API deployment exists" "kubectl get deployment api -n api" test_command "API pods running" "kubectl get pods -n api -l app=api --field-selector=status.phase=Running --no-headers | wc -l | grep -q '[1-9]'" test_command "API service exists" "kubectl get service api -n api" test_command "API ingress exists" "kubectl get ingress api -n api" echo "" # Portal Deployment log_info "=== Portal Deployment ===" test_command "Portal deployment exists" "kubectl get deployment portal -n portal" test_command "Portal pods running" "kubectl get pods -n portal -l app=portal --field-selector=status.phase=Running --no-headers | wc -l | grep -q '[1-9]'" echo "" # Keycloak Deployment log_info "=== Keycloak Deployment ===" test_command "Keycloak deployment exists" "kubectl get deployment keycloak -n keycloak" test_command "Keycloak pods running" "kubectl get pods -n keycloak -l app=keycloak --field-selector=status.phase=Running --no-headers | wc -l | grep -q '[1-9]'" test_command "Keycloak service exists" "kubectl get service keycloak -n keycloak" echo "" # Database log_info "=== Database ===" if kubectl get deployment postgres -n api &>/dev/null || kubectl get statefulset postgres -n api &>/dev/null; then test_command "PostgreSQL exists" "kubectl get deployment postgres -n api || kubectl get statefulset postgres -n api" test_command "PostgreSQL pods running" "kubectl get pods -n api -l app=postgres --field-selector=status.phase=Running --no-headers | wc -l | grep -q '[1-9]'" else log_skip "PostgreSQL (external database)" fi echo "" # Crossplane log_info "=== Crossplane ===" test_command "Crossplane installed" "kubectl get deployment crossplane -n crossplane-system" test_command "Proxmox provider installed" "kubectl get deployment crossplane-provider-proxmox -n crossplane-system" echo "" # Monitoring log_info "=== Monitoring ===" if kubectl get deployment prometheus -n monitoring &>/dev/null || kubectl get statefulset prometheus -n monitoring &>/dev/null; then test_command "Prometheus installed" "kubectl get deployment prometheus -n monitoring || kubectl get statefulset prometheus -n monitoring" else log_skip "Prometheus (not deployed)" fi if kubectl get deployment grafana -n monitoring &>/dev/null; then test_command "Grafana installed" "kubectl get deployment grafana -n monitoring" else log_skip "Grafana (not deployed)" fi echo "" # Health Checks log_info "=== Health Checks ===" API_URL="${API_URL:-https://api.sankofa.nexus}" KEYCLOAK_URL="${KEYCLOAK_URL:-https://keycloak.sankofa.nexus}" if [ -n "$API_URL" ]; then test_http "API health endpoint" "$API_URL/health" 200 test_graphql "GraphQL health query" "{ health { status } }" "$API_URL/graphql" else log_skip "API health check (API_URL not set)" fi if [ -n "$KEYCLOAK_URL" ]; then test_http "Keycloak health endpoint" "$KEYCLOAK_URL/health/ready" 200 else log_skip "Keycloak health check (KEYCLOAK_URL not set)" fi echo "" # Secrets log_info "=== Secrets ===" test_command "Keycloak credentials secret" "kubectl get secret keycloak-credentials -n keycloak" test_command "Keycloak client secrets" "kubectl get secret keycloak-client-secrets -n keycloak" echo "" # Summary echo "" log_info "=== Test Summary ===" echo -e "${GREEN}Passed:${NC} $PASSED" echo -e "${RED}Failed:${NC} $FAILED" echo -e "${YELLOW}Skipped:${NC} $SKIPPED" echo "" if [ $FAILED -eq 0 ]; then log_success "All tests passed!" exit 0 else log_error "Some tests failed. Please review the output above." exit 1 fi } main "$@"