REFACTOR - Database logic
This commit is contained in:
295
test_docker_build.py
Normal file
295
test_docker_build.py
Normal file
@@ -0,0 +1,295 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Docker Build and Compose Test Script
|
||||
Tests that each service can be built correctly and docker-compose starts without errors
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import time
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
def run_command(cmd, cwd=None, timeout=300, capture_output=True):
|
||||
"""Run a shell command with timeout and error handling"""
|
||||
try:
|
||||
print(f"Running: {cmd}")
|
||||
if capture_output:
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
shell=True,
|
||||
cwd=cwd,
|
||||
timeout=timeout,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
else:
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
shell=True,
|
||||
cwd=cwd,
|
||||
timeout=timeout
|
||||
)
|
||||
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 check_docker_available():
|
||||
"""Check if Docker is available and running"""
|
||||
print("🐳 Checking Docker availability...")
|
||||
|
||||
# Check if docker command exists
|
||||
result = run_command("which docker")
|
||||
if result.returncode != 0:
|
||||
print("❌ Docker command not found. Please install Docker.")
|
||||
return False
|
||||
|
||||
# Check if Docker daemon is running
|
||||
result = run_command("docker version")
|
||||
if result.returncode != 0:
|
||||
print("❌ Docker daemon is not running. Please start Docker.")
|
||||
return False
|
||||
|
||||
# Check if docker-compose is available
|
||||
result = run_command("docker compose version")
|
||||
if result.returncode != 0:
|
||||
# Try legacy docker-compose
|
||||
result = run_command("docker-compose version")
|
||||
if result.returncode != 0:
|
||||
print("❌ docker-compose not found. Please install docker-compose.")
|
||||
return False
|
||||
else:
|
||||
print("✅ Using legacy docker-compose")
|
||||
else:
|
||||
print("✅ Using Docker Compose v2")
|
||||
|
||||
print("✅ Docker is available and running")
|
||||
return True
|
||||
|
||||
def test_individual_builds():
|
||||
"""Test building each service individually"""
|
||||
print("\n🔨 Testing individual service builds...")
|
||||
|
||||
services = [
|
||||
"auth-service",
|
||||
"tenant-service",
|
||||
"training-service",
|
||||
"forecasting-service",
|
||||
"data-service",
|
||||
"notification-service"
|
||||
]
|
||||
|
||||
build_results = {}
|
||||
|
||||
for service in services:
|
||||
print(f"\n--- Building {service} ---")
|
||||
|
||||
dockerfile_path = f"./services/{service.replace('-service', '')}/Dockerfile"
|
||||
if not os.path.exists(dockerfile_path):
|
||||
print(f"❌ Dockerfile not found: {dockerfile_path}")
|
||||
build_results[service] = False
|
||||
continue
|
||||
|
||||
# Build the service
|
||||
cmd = f"docker build -t bakery/{service}:test -f {dockerfile_path} ."
|
||||
result = run_command(cmd, timeout=600)
|
||||
|
||||
if result and result.returncode == 0:
|
||||
print(f"✅ {service} built successfully")
|
||||
build_results[service] = True
|
||||
else:
|
||||
print(f"❌ {service} build failed")
|
||||
if result and result.stderr:
|
||||
print(f"Error: {result.stderr}")
|
||||
build_results[service] = False
|
||||
|
||||
return build_results
|
||||
|
||||
def test_docker_compose_config():
|
||||
"""Test docker-compose configuration"""
|
||||
print("\n📋 Testing docker-compose configuration...")
|
||||
|
||||
# Check if docker-compose.yml exists
|
||||
if not os.path.exists("docker-compose.yml"):
|
||||
print("❌ docker-compose.yml not found")
|
||||
return False
|
||||
|
||||
# Check if .env file exists
|
||||
if not os.path.exists(".env"):
|
||||
print("❌ .env file not found")
|
||||
return False
|
||||
|
||||
# Validate docker-compose configuration
|
||||
result = run_command("docker compose config")
|
||||
if result.returncode != 0:
|
||||
# Try legacy docker-compose
|
||||
result = run_command("docker-compose config")
|
||||
if result.returncode != 0:
|
||||
print("❌ docker-compose configuration validation failed")
|
||||
if result.stderr:
|
||||
print(f"Error: {result.stderr}")
|
||||
return False
|
||||
|
||||
print("✅ docker-compose configuration is valid")
|
||||
return True
|
||||
|
||||
def test_essential_services_startup():
|
||||
"""Test starting essential infrastructure services only"""
|
||||
print("\n🚀 Testing essential services startup...")
|
||||
|
||||
# Start only databases and infrastructure - not the application services
|
||||
essential_services = [
|
||||
"redis",
|
||||
"rabbitmq",
|
||||
"auth-db",
|
||||
"data-db"
|
||||
]
|
||||
|
||||
try:
|
||||
# Stop any running containers first
|
||||
print("Stopping any existing containers...")
|
||||
run_command("docker compose down", timeout=120)
|
||||
|
||||
# Start essential services
|
||||
services_str = " ".join(essential_services)
|
||||
cmd = f"docker compose up -d {services_str}"
|
||||
result = run_command(cmd, timeout=300)
|
||||
|
||||
if result.returncode != 0:
|
||||
print("❌ Failed to start essential services")
|
||||
if result.stderr:
|
||||
print(f"Error: {result.stderr}")
|
||||
return False
|
||||
|
||||
# Wait for services to be ready
|
||||
print("Waiting for services to be ready...")
|
||||
time.sleep(30)
|
||||
|
||||
# Check service health
|
||||
print("Checking service health...")
|
||||
result = run_command("docker compose ps")
|
||||
if result.returncode == 0:
|
||||
print("Services status:")
|
||||
print(result.stdout)
|
||||
|
||||
print("✅ Essential services started successfully")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error during essential services test: {e}")
|
||||
return False
|
||||
finally:
|
||||
# Cleanup
|
||||
print("Cleaning up essential services test...")
|
||||
run_command("docker compose down", timeout=120)
|
||||
|
||||
def cleanup_docker_resources():
|
||||
"""Clean up Docker resources"""
|
||||
print("\n🧹 Cleaning up Docker resources...")
|
||||
|
||||
# Remove test images
|
||||
services = ["auth-service", "tenant-service", "training-service",
|
||||
"forecasting-service", "data-service", "notification-service"]
|
||||
|
||||
for service in services:
|
||||
run_command(f"docker rmi bakery/{service}:test", timeout=30)
|
||||
|
||||
# Remove dangling images
|
||||
run_command("docker image prune -f", timeout=60)
|
||||
|
||||
print("✅ Docker resources cleaned up")
|
||||
|
||||
def main():
|
||||
"""Main test function"""
|
||||
print("🔍 DOCKER BUILD AND COMPOSE TESTING")
|
||||
print("=" * 50)
|
||||
|
||||
base_path = Path(__file__).parent
|
||||
os.chdir(base_path)
|
||||
|
||||
# Test results
|
||||
test_results = {
|
||||
"docker_available": False,
|
||||
"compose_config": False,
|
||||
"individual_builds": {},
|
||||
"essential_services": False
|
||||
}
|
||||
|
||||
# Check Docker availability
|
||||
test_results["docker_available"] = check_docker_available()
|
||||
if not test_results["docker_available"]:
|
||||
print("\n❌ Docker tests cannot proceed without Docker")
|
||||
return 1
|
||||
|
||||
# Test docker-compose configuration
|
||||
test_results["compose_config"] = test_docker_compose_config()
|
||||
|
||||
# Test individual builds (this might take a while)
|
||||
print("\n⚠️ Individual builds test can take several minutes...")
|
||||
user_input = input("Run individual service builds? (y/N): ").lower()
|
||||
|
||||
if user_input == 'y':
|
||||
test_results["individual_builds"] = test_individual_builds()
|
||||
else:
|
||||
print("Skipping individual builds test")
|
||||
test_results["individual_builds"] = {"skipped": True}
|
||||
|
||||
# Test essential services startup
|
||||
print("\n⚠️ Essential services test will start Docker containers...")
|
||||
user_input = input("Test essential services startup? (y/N): ").lower()
|
||||
|
||||
if user_input == 'y':
|
||||
test_results["essential_services"] = test_essential_services_startup()
|
||||
else:
|
||||
print("Skipping essential services test")
|
||||
test_results["essential_services"] = "skipped"
|
||||
|
||||
# Print final results
|
||||
print("\n" + "=" * 50)
|
||||
print("📋 TEST RESULTS SUMMARY")
|
||||
print("=" * 50)
|
||||
|
||||
print(f"Docker Available: {'✅' if test_results['docker_available'] else '❌'}")
|
||||
print(f"Docker Compose Config: {'✅' if test_results['compose_config'] else '❌'}")
|
||||
|
||||
if "skipped" in test_results["individual_builds"]:
|
||||
print("Individual Builds: ⏭️ Skipped")
|
||||
else:
|
||||
builds = test_results["individual_builds"]
|
||||
success_count = sum(1 for v in builds.values() if v)
|
||||
total_count = len(builds)
|
||||
print(f"Individual Builds: {success_count}/{total_count} ✅")
|
||||
|
||||
for service, success in builds.items():
|
||||
status = "✅" if success else "❌"
|
||||
print(f" - {service}: {status}")
|
||||
|
||||
if test_results["essential_services"] == "skipped":
|
||||
print("Essential Services: ⏭️ Skipped")
|
||||
else:
|
||||
print(f"Essential Services: {'✅' if test_results['essential_services'] else '❌'}")
|
||||
|
||||
# Cleanup
|
||||
if user_input == 'y' and "skipped" not in test_results["individual_builds"]:
|
||||
cleanup_docker_resources()
|
||||
|
||||
# Determine overall success
|
||||
if (test_results["docker_available"] and
|
||||
test_results["compose_config"] and
|
||||
(test_results["individual_builds"] == {"skipped": True} or
|
||||
all(test_results["individual_builds"].values())) and
|
||||
(test_results["essential_services"] == "skipped" or test_results["essential_services"])):
|
||||
print("\n🎉 ALL TESTS PASSED")
|
||||
return 0
|
||||
else:
|
||||
print("\n❌ SOME TESTS FAILED")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit_code = main()
|
||||
sys.exit(exit_code)
|
||||
Reference in New Issue
Block a user