#!/usr/bin/env bash # ============================================================================ # Functional Test: Tenant Deletion System # ============================================================================ # Tests the complete tenant deletion workflow with service tokens # # Usage: # ./scripts/functional_test_deletion.sh # # Example: # ./scripts/functional_test_deletion.sh dbc2128a-7539-470c-94b9-c1e37031bd77 # # ============================================================================ set -e # Exit on error # Require bash 4+ for associative arrays if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then echo "Error: This script requires bash 4.0 or higher" echo "Current version: ${BASH_VERSION}" exit 1 fi # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration TENANT_ID="${1:-dbc2128a-7539-470c-94b9-c1e37031bd77}" SERVICE_TOKEN="${SERVICE_TOKEN:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZW5hbnQtZGVsZXRpb24tb3JjaGVzdHJhdG9yIiwidXNlcl9pZCI6InRlbmFudC1kZWxldGlvbi1vcmNoZXN0cmF0b3IiLCJzZXJ2aWNlIjoidGVuYW50LWRlbGV0aW9uLW9yY2hlc3RyYXRvciIsInR5cGUiOiJzZXJ2aWNlIiwiaXNfc2VydmljZSI6dHJ1ZSwicm9sZSI6ImFkbWluIiwiZW1haWwiOiJ0ZW5hbnQtZGVsZXRpb24tb3JjaGVzdHJhdG9yQGludGVybmFsLnNlcnZpY2UiLCJleHAiOjE3OTM0NDIwMzAsImlhdCI6MTc2MTkwNjAzMCwiaXNzIjoiYmFrZXJ5LWF1dGgifQ.I6mWLpkRim2fJ1v9WH24g4YT3-ZGbuFXxCorZxhPp6c}" # Test mode (preview or delete) TEST_MODE="${2:-preview}" # preview or delete # Service list with their endpoints declare -A SERVICES=( ["orders"]="orders-service:8000" ["inventory"]="inventory-service:8000" ["recipes"]="recipes-service:8000" ["sales"]="sales-service:8000" ["production"]="production-service:8000" ["suppliers"]="suppliers-service:8000" ["pos"]="pos-service:8000" ["external"]="city-service:8000" ["forecasting"]="forecasting-service:8000" ["training"]="training-service:8000" ["alert-processor"]="alert-processor-service:8000" ["notification"]="notification-service:8000" ) # Results tracking TOTAL_SERVICES=12 SUCCESSFUL_TESTS=0 FAILED_TESTS=0 declare -a FAILED_SERVICES # ============================================================================ # Helper Functions # ============================================================================ print_header() { echo -e "${BLUE}============================================================================${NC}" echo -e "${BLUE}$1${NC}" echo -e "${BLUE}============================================================================${NC}" } print_success() { echo -e "${GREEN}✓${NC} $1" } print_error() { echo -e "${RED}✗${NC} $1" } print_warning() { echo -e "${YELLOW}⚠${NC} $1" } print_info() { echo -e "${BLUE}ℹ${NC} $1" } # ============================================================================ # Test Functions # ============================================================================ test_service_preview() { local service_name=$1 local service_host=$2 local endpoint_path=$3 echo "" echo -e "${BLUE}Testing ${service_name}...${NC}" # Get running pod local pod=$(kubectl get pods -n bakery-ia -l app=${service_name}-service 2>/dev/null | grep Running | head -1 | awk '{print $1}') if [ -z "$pod" ]; then print_error "No running pod found for ${service_name}" FAILED_TESTS=$((FAILED_TESTS + 1)) FAILED_SERVICES+=("${service_name}") return 1 fi print_info "Pod: ${pod}" # Execute request inside pod local response=$(kubectl exec -n bakery-ia "$pod" -- curl -s -w "\n%{http_code}" \ -H "Authorization: Bearer ${SERVICE_TOKEN}" \ "http://localhost:8000${endpoint_path}/tenant/${TENANT_ID}/deletion-preview" 2>&1) local http_code=$(echo "$response" | tail -1) local body=$(echo "$response" | sed '$d') if [ "$http_code" = "200" ]; then print_success "Preview successful (HTTP ${http_code})" # Parse and display counts local total_records=$(echo "$body" | grep -o '"total_records":[0-9]*' | cut -d':' -f2 || echo "0") print_info "Records to delete: ${total_records}" # Show breakdown if available echo "$body" | python3 -m json.tool 2>/dev/null | grep -A50 "breakdown" | head -20 || echo "" SUCCESSFUL_TESTS=$((SUCCESSFUL_TESTS + 1)) return 0 elif [ "$http_code" = "401" ]; then print_error "Authentication failed (HTTP ${http_code})" print_warning "Service token may be invalid or expired" echo "$body" FAILED_TESTS=$((FAILED_TESTS + 1)) FAILED_SERVICES+=("${service_name}") return 1 elif [ "$http_code" = "403" ]; then print_error "Authorization failed (HTTP ${http_code})" print_warning "Service token not recognized as service" echo "$body" FAILED_TESTS=$((FAILED_TESTS + 1)) FAILED_SERVICES+=("${service_name}") return 1 elif [ "$http_code" = "404" ]; then print_error "Endpoint not found (HTTP ${http_code})" print_warning "Deletion endpoint may not be implemented" FAILED_TESTS=$((FAILED_TESTS + 1)) FAILED_SERVICES+=("${service_name}") return 1 elif [ "$http_code" = "500" ]; then print_error "Server error (HTTP ${http_code})" echo "$body" | head -5 FAILED_TESTS=$((FAILED_TESTS + 1)) FAILED_SERVICES+=("${service_name}") return 1 else print_error "Unexpected response (HTTP ${http_code})" echo "$body" | head -5 FAILED_TESTS=$((FAILED_TESTS + 1)) FAILED_SERVICES+=("${service_name}") return 1 fi } test_service_deletion() { local service_name=$1 local service_host=$2 local endpoint_path=$3 echo "" echo -e "${BLUE}Deleting data in ${service_name}...${NC}" # Get running pod local pod=$(kubectl get pods -n bakery-ia -l app=${service_name}-service 2>/dev/null | grep Running | head -1 | awk '{print $1}') if [ -z "$pod" ]; then print_error "No running pod found for ${service_name}" FAILED_TESTS=$((FAILED_TESTS + 1)) FAILED_SERVICES+=("${service_name}") return 1 fi # Execute deletion request inside pod local response=$(kubectl exec -n bakery-ia "$pod" -- curl -s -w "\n%{http_code}" \ -X DELETE \ -H "Authorization: Bearer ${SERVICE_TOKEN}" \ "http://localhost:8000${endpoint_path}/tenant/${TENANT_ID}" 2>&1) local http_code=$(echo "$response" | tail -1) local body=$(echo "$response" | sed '$d') if [ "$http_code" = "200" ]; then print_success "Deletion successful (HTTP ${http_code})" # Parse and display deletion summary local total_deleted=$(echo "$body" | grep -o '"total_records_deleted":[0-9]*' | cut -d':' -f2 || echo "0") print_info "Records deleted: ${total_deleted}" SUCCESSFUL_TESTS=$((SUCCESSFUL_TESTS + 1)) return 0 else print_error "Deletion failed (HTTP ${http_code})" echo "$body" | head -5 FAILED_TESTS=$((FAILED_TESTS + 1)) FAILED_SERVICES+=("${service_name}") return 1 fi } # ============================================================================ # Main Test Execution # ============================================================================ main() { print_header "Tenant Deletion System - Functional Test" echo "" print_info "Tenant ID: ${TENANT_ID}" print_info "Test Mode: ${TEST_MODE}" print_info "Services to test: ${TOTAL_SERVICES}" echo "" # Verify service token print_info "Verifying service token..." if python scripts/generate_service_token.py --verify "${SERVICE_TOKEN}" > /dev/null 2>&1; then print_success "Service token is valid" else print_error "Service token is invalid or expired" exit 1 fi echo "" print_header "Phase 1: Testing Service Previews" # Test each service preview test_service_preview "orders" "orders-service:8000" "/api/v1/orders" test_service_preview "inventory" "inventory-service:8000" "/api/v1/inventory" test_service_preview "recipes" "recipes-service:8000" "/api/v1/recipes" test_service_preview "sales" "sales-service:8000" "/api/v1/sales" test_service_preview "production" "production-service:8000" "/api/v1/production" test_service_preview "suppliers" "suppliers-service:8000" "/api/v1/suppliers" test_service_preview "pos" "pos-service:8000" "/api/v1/pos" test_service_preview "external" "city-service:8000" "/api/v1/nominatim" test_service_preview "forecasting" "forecasting-service:8000" "/api/v1/forecasting" test_service_preview "training" "training-service:8000" "/api/v1/training" test_service_preview "alert-processor" "alert-processor-service:8000" "/api/v1/analytics" test_service_preview "notification" "notification-service:8000" "/api/v1/notifications" # Summary echo "" print_header "Preview Test Results" echo -e "Total Services: ${TOTAL_SERVICES}" echo -e "${GREEN}Successful:${NC} ${SUCCESSFUL_TESTS}/${TOTAL_SERVICES}" echo -e "${RED}Failed:${NC} ${FAILED_TESTS}/${TOTAL_SERVICES}" if [ ${FAILED_TESTS} -gt 0 ]; then echo "" print_warning "Failed Services:" for service in "${FAILED_SERVICES[@]}"; do echo " - ${service}" done fi # Ask for confirmation before actual deletion if [ "$TEST_MODE" = "delete" ]; then echo "" print_header "Phase 2: Actual Deletion" print_warning "This will PERMANENTLY delete data for tenant ${TENANT_ID}" print_warning "This operation is IRREVERSIBLE" echo "" read -p "Are you sure you want to proceed? (yes/no): " confirm if [ "$confirm" != "yes" ]; then print_info "Deletion cancelled by user" exit 0 fi # Reset counters SUCCESSFUL_TESTS=0 FAILED_TESTS=0 FAILED_SERVICES=() # Execute deletions test_service_deletion "orders" "orders-service:8000" "/api/v1/orders" test_service_deletion "inventory" "inventory-service:8000" "/api/v1/inventory" test_service_deletion "recipes" "recipes-service:8000" "/api/v1/recipes" test_service_deletion "sales" "sales-service:8000" "/api/v1/sales" test_service_deletion "production" "production-service:8000" "/api/v1/production" test_service_deletion "suppliers" "suppliers-service:8000" "/api/v1/suppliers" test_service_deletion "pos" "pos-service:8000" "/api/v1/pos" test_service_deletion "external" "city-service:8000" "/api/v1/nominatim" test_service_deletion "forecasting" "forecasting-service:8000" "/api/v1/forecasting" test_service_deletion "training" "training-service:8000" "/api/v1/training" test_service_deletion "alert-processor" "alert-processor-service:8000" "/api/v1/analytics" test_service_deletion "notification" "notification-service:8000" "/api/v1/notifications" # Deletion summary echo "" print_header "Deletion Test Results" echo -e "Total Services: ${TOTAL_SERVICES}" echo -e "${GREEN}Successful:${NC} ${SUCCESSFUL_TESTS}/${TOTAL_SERVICES}" echo -e "${RED}Failed:${NC} ${FAILED_TESTS}/${TOTAL_SERVICES}" if [ ${FAILED_TESTS} -gt 0 ]; then echo "" print_warning "Failed Services:" for service in "${FAILED_SERVICES[@]}"; do echo " - ${service}" done fi fi echo "" print_header "Test Complete" if [ ${FAILED_TESTS} -eq 0 ]; then print_success "All tests passed successfully!" exit 0 else print_error "Some tests failed. See details above." exit 1 fi } # Run main function main