199 lines
6.2 KiB
Python
199 lines
6.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Services Startup Test Script
|
|
Tests that services actually start and respond to health checks
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import time
|
|
import requests
|
|
from pathlib import Path
|
|
|
|
def run_command(cmd, cwd=None, timeout=300):
|
|
"""Run a shell command with timeout"""
|
|
try:
|
|
print(f"Running: {cmd}")
|
|
result = subprocess.run(
|
|
cmd,
|
|
shell=True,
|
|
cwd=cwd,
|
|
timeout=timeout,
|
|
capture_output=True,
|
|
text=True
|
|
)
|
|
return result
|
|
except subprocess.TimeoutExpired:
|
|
print(f"Command timed out after {timeout} seconds: {cmd}")
|
|
return None
|
|
except Exception as e:
|
|
print(f"Error running command: {e}")
|
|
return None
|
|
|
|
def wait_for_service(url, max_attempts=30, delay=10):
|
|
"""Wait for a service to become healthy"""
|
|
print(f"Waiting for service at {url}...")
|
|
|
|
for attempt in range(max_attempts):
|
|
try:
|
|
response = requests.get(url, timeout=5)
|
|
if response.status_code == 200:
|
|
print(f"✅ Service at {url} is healthy")
|
|
return True
|
|
except requests.exceptions.RequestException:
|
|
pass
|
|
|
|
if attempt < max_attempts - 1:
|
|
print(f"Attempt {attempt + 1}/{max_attempts} failed, waiting {delay}s...")
|
|
time.sleep(delay)
|
|
|
|
print(f"❌ Service at {url} did not become healthy")
|
|
return False
|
|
|
|
def test_essential_services():
|
|
"""Test starting essential services and one application service"""
|
|
print("🚀 Testing essential services startup...")
|
|
|
|
try:
|
|
# Stop any running containers
|
|
print("Stopping any existing containers...")
|
|
run_command("docker compose down", timeout=120)
|
|
|
|
# Start infrastructure services first
|
|
print("Starting infrastructure services...")
|
|
infra_cmd = "docker compose up -d redis rabbitmq auth-db data-db"
|
|
result = run_command(infra_cmd, timeout=300)
|
|
|
|
if result.returncode != 0:
|
|
print("❌ Failed to start infrastructure services")
|
|
if result.stderr:
|
|
print(f"Error: {result.stderr}")
|
|
return False
|
|
|
|
# Wait for infrastructure to be ready
|
|
print("Waiting for infrastructure services...")
|
|
time.sleep(30)
|
|
|
|
# Start one application service (auth-service) to test
|
|
print("Starting auth service...")
|
|
app_cmd = "docker compose up -d auth-service"
|
|
result = run_command(app_cmd, timeout=300)
|
|
|
|
if result.returncode != 0:
|
|
print("❌ Failed to start auth service")
|
|
if result.stderr:
|
|
print(f"Error: {result.stderr}")
|
|
return False
|
|
|
|
# Wait for auth service to be ready
|
|
print("Waiting for auth service to start...")
|
|
time.sleep(45) # Give more time for app service
|
|
|
|
# Check if auth service is healthy
|
|
auth_healthy = wait_for_service("http://localhost:8001/health", max_attempts=10, delay=5)
|
|
|
|
if not auth_healthy:
|
|
# Show logs to debug
|
|
print("Showing auth service logs...")
|
|
logs_result = run_command("docker compose logs auth-service", timeout=30)
|
|
if logs_result and logs_result.stdout:
|
|
print("Auth service logs:")
|
|
print(logs_result.stdout[-2000:]) # Last 2000 chars
|
|
|
|
return auth_healthy
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error during services test: {e}")
|
|
return False
|
|
|
|
def show_service_status():
|
|
"""Show the status of all containers"""
|
|
print("\n📊 Current container status:")
|
|
result = run_command("docker compose ps", timeout=30)
|
|
if result and result.stdout:
|
|
print(result.stdout)
|
|
else:
|
|
print("Could not get container status")
|
|
|
|
def test_docker_compose_basic():
|
|
"""Test basic docker-compose functionality"""
|
|
print("🐳 Testing basic docker-compose functionality...")
|
|
|
|
try:
|
|
# Test docker-compose up --dry-run if available
|
|
result = run_command("docker compose config --services", timeout=30)
|
|
|
|
if result.returncode == 0:
|
|
services = result.stdout.strip().split('\n')
|
|
print(f"✅ Found {len(services)} services in docker-compose.yml:")
|
|
for service in services:
|
|
print(f" - {service}")
|
|
return True
|
|
else:
|
|
print("❌ Could not list services from docker-compose.yml")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error testing docker-compose: {e}")
|
|
return False
|
|
|
|
def cleanup():
|
|
"""Clean up all containers and resources"""
|
|
print("\n🧹 Cleaning up...")
|
|
|
|
# Stop all containers
|
|
run_command("docker compose down", timeout=180)
|
|
|
|
# Remove unused images (only test images)
|
|
run_command("docker image prune -f", timeout=60)
|
|
|
|
print("✅ Cleanup completed")
|
|
|
|
def main():
|
|
"""Main test function"""
|
|
print("🧪 SERVICES STARTUP TEST")
|
|
print("=" * 40)
|
|
|
|
base_path = Path(__file__).parent
|
|
os.chdir(base_path)
|
|
|
|
success = True
|
|
|
|
try:
|
|
# Test basic docker-compose functionality
|
|
if not test_docker_compose_basic():
|
|
success = False
|
|
|
|
# Test essential services startup
|
|
if not test_essential_services():
|
|
success = False
|
|
|
|
# Show final status
|
|
show_service_status()
|
|
|
|
except KeyboardInterrupt:
|
|
print("\n⚠️ Test interrupted by user")
|
|
success = False
|
|
except Exception as e:
|
|
print(f"\n❌ Unexpected error: {e}")
|
|
success = False
|
|
finally:
|
|
# Always cleanup
|
|
cleanup()
|
|
|
|
# Final result
|
|
print("\n" + "=" * 40)
|
|
if success:
|
|
print("🎉 SERVICES STARTUP TEST PASSED!")
|
|
print("✅ Services can build and start successfully")
|
|
print("💡 Your docker-compose setup is working correctly")
|
|
return 0
|
|
else:
|
|
print("❌ SERVICES STARTUP TEST FAILED")
|
|
print("⚠️ Some services may have issues starting")
|
|
return 1
|
|
|
|
if __name__ == "__main__":
|
|
exit_code = main()
|
|
sys.exit(exit_code) |