| #!/bin/bash |
|
|
| |
| |
|
|
| set -e |
|
|
| |
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| source "$SCRIPT_DIR/deployment-utils.sh" |
|
|
| |
| VALIDATION_TIMEOUT=300 |
| TEST_USER_EMAIL="test@example.com" |
| TEST_USER_PASSWORD="testpassword123" |
|
|
| |
| declare -A VALIDATION_RESULTS |
|
|
| |
| test_user_registration() { |
| local backend_url=$1 |
| |
| log "Testing user registration..." |
| |
| local response |
| response=$(curl -s -w "%{http_code}" \ |
| -X POST \ |
| -H "Content-Type: application/json" \ |
| -d "{\"email\":\"$TEST_USER_EMAIL\",\"password\":\"$TEST_USER_PASSWORD\"}" \ |
| "$backend_url/auth/register" 2>/dev/null || echo "000") |
| |
| local status_code="${response: -3}" |
| local body="${response%???}" |
| |
| case $status_code in |
| 201) |
| success "User registration successful" |
| VALIDATION_RESULTS["User Registration"]="PASS" |
| return 0 |
| ;; |
| 400) |
| if echo "$body" | grep -q "already exists"; then |
| success "User registration validation passed (user already exists)" |
| VALIDATION_RESULTS["User Registration"]="PASS" |
| return 0 |
| else |
| error "User registration failed: $body" |
| VALIDATION_RESULTS["User Registration"]="FAIL" |
| return 1 |
| fi |
| ;; |
| *) |
| error "User registration failed with HTTP $status_code: $body" |
| VALIDATION_RESULTS["User Registration"]="FAIL" |
| return 1 |
| ;; |
| esac |
| } |
|
|
| |
| test_user_login() { |
| local backend_url=$1 |
| |
| log "Testing user login..." |
| |
| local response |
| response=$(curl -s -w "%{http_code}" \ |
| -X POST \ |
| -H "Content-Type: application/json" \ |
| -d "{\"email\":\"$TEST_USER_EMAIL\",\"password\":\"$TEST_USER_PASSWORD\"}" \ |
| "$backend_url/auth/jwt/login" 2>/dev/null || echo "000") |
| |
| local status_code="${response: -3}" |
| local body="${response%???}" |
| |
| if [ "$status_code" = "200" ]; then |
| |
| JWT_TOKEN=$(echo "$body" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4) |
| |
| if [ -n "$JWT_TOKEN" ]; then |
| success "User login successful, JWT token obtained" |
| VALIDATION_RESULTS["User Login"]="PASS" |
| return 0 |
| else |
| error "User login failed: No JWT token in response" |
| VALIDATION_RESULTS["User Login"]="FAIL" |
| return 1 |
| fi |
| else |
| error "User login failed with HTTP $status_code: $body" |
| VALIDATION_RESULTS["User Login"]="FAIL" |
| return 1 |
| fi |
| } |
|
|
| |
| test_document_upload() { |
| local backend_url=$1 |
| local jwt_token=$2 |
| |
| log "Testing document upload..." |
| |
| |
| local test_doc="/tmp/test_document.txt" |
| echo "This is a test document for validation purposes. It contains sample text to test the RAG functionality." > "$test_doc" |
| |
| local response |
| response=$(curl -s -w "%{http_code}" \ |
| -X POST \ |
| -H "Authorization: Bearer $jwt_token" \ |
| -F "file=@$test_doc" \ |
| "$backend_url/upload" 2>/dev/null || echo "000") |
| |
| local status_code="${response: -3}" |
| local body="${response%???}" |
| |
| |
| rm -f "$test_doc" |
| |
| if [ "$status_code" = "200" ]; then |
| success "Document upload successful" |
| VALIDATION_RESULTS["Document Upload"]="PASS" |
| return 0 |
| else |
| error "Document upload failed with HTTP $status_code: $body" |
| VALIDATION_RESULTS["Document Upload"]="FAIL" |
| return 1 |
| fi |
| } |
|
|
| |
| test_query_functionality() { |
| local backend_url=$1 |
| local jwt_token=$2 |
| |
| log "Testing query functionality..." |
| |
| local test_query="What is this document about?" |
| |
| local response |
| response=$(curl -s -w "%{http_code}" \ |
| -X POST \ |
| -H "Content-Type: application/json" \ |
| -H "Authorization: Bearer $jwt_token" \ |
| -d "{\"query\":\"$test_query\"}" \ |
| "$backend_url/query" 2>/dev/null || echo "000") |
| |
| local status_code="${response: -3}" |
| local body="${response%???}" |
| |
| if [ "$status_code" = "200" ]; then |
| if echo "$body" | grep -q "response"; then |
| success "Query functionality successful" |
| VALIDATION_RESULTS["Query Functionality"]="PASS" |
| return 0 |
| else |
| error "Query functionality failed: No response in body" |
| VALIDATION_RESULTS["Query Functionality"]="FAIL" |
| return 1 |
| fi |
| else |
| error "Query functionality failed with HTTP $status_code: $body" |
| VALIDATION_RESULTS["Query Functionality"]="FAIL" |
| return 1 |
| fi |
| } |
|
|
| |
| test_frontend_accessibility() { |
| local frontend_url=$1 |
| |
| log "Testing frontend accessibility..." |
| |
| local response |
| response=$(curl -s -w "%{http_code}" "$frontend_url" 2>/dev/null || echo "000") |
| |
| local status_code="${response: -3}" |
| local body="${response%???}" |
| |
| if [ "$status_code" = "200" ]; then |
| if echo "$body" | grep -q -i "knowledge.*assistant\|rag\|react"; then |
| success "Frontend is accessible and appears to be the correct application" |
| VALIDATION_RESULTS["Frontend Accessibility"]="PASS" |
| return 0 |
| else |
| warning "Frontend is accessible but content validation failed" |
| VALIDATION_RESULTS["Frontend Accessibility"]="PARTIAL" |
| return 0 |
| fi |
| else |
| error "Frontend accessibility failed with HTTP $status_code" |
| VALIDATION_RESULTS["Frontend Accessibility"]="FAIL" |
| return 1 |
| fi |
| } |
|
|
| |
| test_api_documentation() { |
| local backend_url=$1 |
| |
| log "Testing API documentation accessibility..." |
| |
| local response |
| response=$(curl -s -w "%{http_code}" "$backend_url/docs" 2>/dev/null || echo "000") |
| |
| local status_code="${response: -3}" |
| |
| if [ "$status_code" = "200" ]; then |
| success "API documentation is accessible" |
| VALIDATION_RESULTS["API Documentation"]="PASS" |
| return 0 |
| else |
| warning "API documentation not accessible (HTTP $status_code)" |
| VALIDATION_RESULTS["API Documentation"]="FAIL" |
| return 1 |
| fi |
| } |
|
|
| |
| test_database_connectivity() { |
| local backend_url=$1 |
| |
| log "Testing database connectivity through API..." |
| |
| |
| local response |
| response=$(curl -s -w "%{http_code}" "$backend_url/health" 2>/dev/null || echo "000") |
| |
| local status_code="${response: -3}" |
| local body="${response%???}" |
| |
| if [ "$status_code" = "200" ]; then |
| if echo "$body" | grep -q -i "database\|db"; then |
| success "Database connectivity test passed" |
| VALIDATION_RESULTS["Database Connectivity"]="PASS" |
| return 0 |
| else |
| warning "Database connectivity status unclear from health endpoint" |
| VALIDATION_RESULTS["Database Connectivity"]="PARTIAL" |
| return 0 |
| fi |
| else |
| error "Database connectivity test failed (health endpoint returned $status_code)" |
| VALIDATION_RESULTS["Database Connectivity"]="FAIL" |
| return 1 |
| fi |
| } |
|
|
| |
| test_qdrant_connectivity() { |
| local qdrant_url=$1 |
| |
| log "Testing Qdrant connectivity..." |
| |
| local response |
| response=$(curl -s -w "%{http_code}" "$qdrant_url/health" 2>/dev/null || echo "000") |
| |
| local status_code="${response: -3}" |
| |
| if [ "$status_code" = "200" ]; then |
| success "Qdrant connectivity test passed" |
| VALIDATION_RESULTS["Qdrant Connectivity"]="PASS" |
| return 0 |
| else |
| error "Qdrant connectivity test failed (HTTP $status_code)" |
| VALIDATION_RESULTS["Qdrant Connectivity"]="FAIL" |
| return 1 |
| fi |
| } |
|
|
| |
| test_external_api_connectivity() { |
| local backend_url=$1 |
| |
| log "Testing external API connectivity..." |
| |
| |
| |
| if [ -n "$GEMINI_API_KEY" ]; then |
| success "Google Gemini API key is configured" |
| VALIDATION_RESULTS["External API Config"]="PASS" |
| elif [ -n "$OPENAI_API_KEY" ]; then |
| success "OpenAI API key is configured" |
| VALIDATION_RESULTS["External API Config"]="PASS" |
| else |
| warning "No external API keys configured" |
| VALIDATION_RESULTS["External API Config"]="FAIL" |
| fi |
| } |
|
|
| |
| test_performance() { |
| local backend_url=$1 |
| local jwt_token=$2 |
| |
| log "Running basic performance test..." |
| |
| local start_time |
| local end_time |
| local duration |
| |
| start_time=$(date +%s.%N) |
| |
| |
| curl -s "$backend_url/health" > /dev/null |
| |
| end_time=$(date +%s.%N) |
| duration=$(echo "$end_time - $start_time" | bc) |
| |
| if (( $(echo "$duration < 2.0" | bc -l) )); then |
| success "Performance test passed (${duration}s response time)" |
| VALIDATION_RESULTS["Performance"]="PASS" |
| elif (( $(echo "$duration < 5.0" | bc -l) )); then |
| warning "Performance test marginal (${duration}s response time)" |
| VALIDATION_RESULTS["Performance"]="PARTIAL" |
| else |
| error "Performance test failed (${duration}s response time)" |
| VALIDATION_RESULTS["Performance"]="FAIL" |
| fi |
| } |
|
|
| |
| generate_validation_report() { |
| echo "" |
| echo "==================================" |
| echo " DEPLOYMENT VALIDATION REPORT" |
| echo "==================================" |
| echo "Timestamp: $(date)" |
| echo "" |
| |
| local pass_count=0 |
| local fail_count=0 |
| local partial_count=0 |
| |
| for test in "${!VALIDATION_RESULTS[@]}"; do |
| local result="${VALIDATION_RESULTS[$test]}" |
| local result_icon="" |
| |
| case $result in |
| "PASS") |
| result_icon="✅" |
| pass_count=$((pass_count + 1)) |
| ;; |
| "FAIL") |
| result_icon="❌" |
| fail_count=$((fail_count + 1)) |
| ;; |
| "PARTIAL") |
| result_icon="⚠️ " |
| partial_count=$((partial_count + 1)) |
| ;; |
| esac |
| |
| printf "%-25s %s %s\n" "$test" "$result_icon" "$result" |
| done |
| |
| echo "" |
| echo "Summary:" |
| echo " Passed: $pass_count" |
| echo " Failed: $fail_count" |
| echo " Partial: $partial_count" |
| echo "" |
| |
| |
| if [ $fail_count -eq 0 ] && [ $partial_count -eq 0 ]; then |
| success "Overall deployment validation: EXCELLENT" |
| return 0 |
| elif [ $fail_count -eq 0 ]; then |
| warning "Overall deployment validation: GOOD (with warnings)" |
| return 0 |
| elif [ $fail_count -le 2 ]; then |
| warning "Overall deployment validation: ACCEPTABLE (minor issues)" |
| return 1 |
| else |
| error "Overall deployment validation: FAILED (major issues)" |
| return 2 |
| fi |
| } |
|
|
| |
| main() { |
| local backend_url="" |
| local frontend_url="" |
| local qdrant_url="" |
| local env_file="" |
| local skip_functional=false |
| local output_file="" |
| |
| |
| while [[ $# -gt 0 ]]; do |
| case $1 in |
| --backend-url) |
| backend_url="$2" |
| shift 2 |
| ;; |
| --frontend-url) |
| frontend_url="$2" |
| shift 2 |
| ;; |
| --qdrant-url) |
| qdrant_url="$2" |
| shift 2 |
| ;; |
| --env-file) |
| env_file="$2" |
| shift 2 |
| ;; |
| --skip-functional) |
| skip_functional=true |
| shift |
| ;; |
| --output) |
| output_file="$2" |
| shift 2 |
| ;; |
| --help) |
| echo "Deployment Validation Script for Knowledge Assistant RAG" |
| echo "" |
| echo "Usage: $0 [OPTIONS]" |
| echo "" |
| echo "Options:" |
| echo " --backend-url URL Backend service URL" |
| echo " --frontend-url URL Frontend service URL" |
| echo " --qdrant-url URL Qdrant service URL" |
| echo " --env-file FILE Environment file to load" |
| echo " --skip-functional Skip functional tests" |
| echo " --output FILE Save report to file" |
| echo " --help Show this help" |
| echo "" |
| exit 0 |
| ;; |
| *) |
| error "Unknown option: $1" |
| exit 1 |
| ;; |
| esac |
| done |
| |
| log "Starting deployment validation..." |
| |
| |
| if [ -n "$env_file" ] && [ -f "$env_file" ]; then |
| source "$env_file" |
| elif [ -f ".env" ]; then |
| source ".env" |
| fi |
| |
| |
| backend_url=${backend_url:-${BACKEND_URL:-"http://localhost:8000"}} |
| frontend_url=${frontend_url:-${FRONTEND_URL:-"http://localhost:3000"}} |
| qdrant_url=${qdrant_url:-"http://${QDRANT_HOST:-localhost}:${QDRANT_PORT:-6333}"} |
| |
| log "Validating deployment with:" |
| log " Backend URL: $backend_url" |
| log " Frontend URL: $frontend_url" |
| log " Qdrant URL: $qdrant_url" |
| |
| |
| wait_for_service "$backend_url/health" 60 5 "Backend" |
| wait_for_service "$frontend_url" 30 5 "Frontend" |
| wait_for_service "$qdrant_url/health" 30 5 "Qdrant" |
| |
| |
| test_frontend_accessibility "$frontend_url" |
| test_api_documentation "$backend_url" |
| test_database_connectivity "$backend_url" |
| test_qdrant_connectivity "$qdrant_url" |
| test_external_api_connectivity "$backend_url" |
| |
| if [ "$skip_functional" != true ]; then |
| |
| if test_user_registration "$backend_url"; then |
| if test_user_login "$backend_url"; then |
| test_document_upload "$backend_url" "$JWT_TOKEN" |
| test_query_functionality "$backend_url" "$JWT_TOKEN" |
| test_performance "$backend_url" "$JWT_TOKEN" |
| fi |
| fi |
| fi |
| |
| |
| local report_output |
| report_output=$(generate_validation_report) |
| echo "$report_output" |
| |
| |
| if [ -n "$output_file" ]; then |
| echo "$report_output" > "$output_file" |
| success "Validation report saved to $output_file" |
| fi |
| |
| |
| local exit_code=$? |
| return $exit_code |
| } |
|
|
| |
| if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then |
| main "$@" |
| fi |