327 lines
12 KiB
Bash
327 lines
12 KiB
Bash
|
|
#!/usr/bin/env bash
|
|||
|
|
# ============================================================================
|
|||
|
|
# Functional Test: Tenant Deletion System
|
|||
|
|
# ============================================================================
|
|||
|
|
# Tests the complete tenant deletion workflow with service tokens
|
|||
|
|
#
|
|||
|
|
# Usage:
|
|||
|
|
# ./scripts/functional_test_deletion.sh <tenant_id>
|
|||
|
|
#
|
|||
|
|
# 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
|