File size: 10,497 Bytes
a963d65 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
#!/usr/bin/env python3
"""
Test Docker Compose Configurations
Test the new Docker Compose setups for local and modal deployments
"""
import os
import sys
import subprocess
import time
import yaml
import tempfile
def test_compose_file_validity():
"""Test that Docker Compose files are valid YAML"""
print("π Testing Docker Compose file validity...")
compose_files = [
"docker-compose.local.yml",
"docker-compose.modal.yml"
]
for compose_file in compose_files:
try:
with open(compose_file, 'r') as f:
yaml.safe_load(f)
print(f"β
{compose_file} is valid YAML")
except yaml.YAMLError as e:
print(f"β {compose_file} invalid YAML: {e}")
return False
except FileNotFoundError:
print(f"β {compose_file} not found")
return False
return True
def test_environment_variables():
"""Test environment variable handling in compose files"""
print("\nπ Testing environment variable defaults...")
# Test local compose file
try:
with open("docker-compose.local.yml", 'r') as f:
local_content = f.read()
# Check for proper environment variable syntax
env_patterns = [
"${GRADIO_PORT:-7860}",
"${A2A_API_PORT:-8000}",
"${OLLAMA_PORT:-11434}",
"${FHIRFLAME_DEV_MODE:-true}",
"${HF_TOKEN}",
"${MISTRAL_API_KEY}"
]
for pattern in env_patterns:
if pattern in local_content:
print(f"β
Local compose has: {pattern}")
else:
print(f"β Local compose missing: {pattern}")
return False
# Test modal compose file
with open("docker-compose.modal.yml", 'r') as f:
modal_content = f.read()
modal_patterns = [
"${MODAL_TOKEN_ID}",
"${MODAL_TOKEN_SECRET}",
"${MODAL_ENDPOINT_URL}",
"${MODAL_L4_HOURLY_RATE:-0.73}",
"${AUTH0_DOMAIN:-}"
]
for pattern in modal_patterns:
if pattern in modal_content:
print(f"β
Modal compose has: {pattern}")
else:
print(f"β Modal compose missing: {pattern}")
return False
return True
except Exception as e:
print(f"β Environment variable test failed: {e}")
return False
def test_compose_services():
"""Test that required services are defined"""
print("\nπ Testing service definitions...")
try:
# Test local services
with open("docker-compose.local.yml", 'r') as f:
local_config = yaml.safe_load(f)
local_services = local_config.get('services', {})
required_local_services = [
'fhirflame-local',
'fhirflame-a2a-api',
'ollama',
'ollama-setup'
]
for service in required_local_services:
if service in local_services:
print(f"β
Local has service: {service}")
else:
print(f"β Local missing service: {service}")
return False
# Test modal services
with open("docker-compose.modal.yml", 'r') as f:
modal_config = yaml.safe_load(f)
modal_services = modal_config.get('services', {})
required_modal_services = [
'fhirflame-modal',
'fhirflame-a2a-modal',
'modal-deployer'
]
for service in required_modal_services:
if service in modal_services:
print(f"β
Modal has service: {service}")
else:
print(f"β Modal missing service: {service}")
return False
return True
except Exception as e:
print(f"β Service definition test failed: {e}")
return False
def test_port_configurations():
"""Test port configurations and conflicts"""
print("\nπ Testing port configurations...")
try:
# Check local ports
with open("docker-compose.local.yml", 'r') as f:
local_config = yaml.safe_load(f)
local_ports = []
for service_name, service_config in local_config['services'].items():
ports = service_config.get('ports', [])
for port_mapping in ports:
if isinstance(port_mapping, str):
host_port = port_mapping.split(':')[0]
# Extract port from env var syntax like ${PORT:-8000}
if 'GRADIO_PORT:-7860' in host_port:
local_ports.append('7860')
elif 'A2A_API_PORT:-8000' in host_port:
local_ports.append('8000')
elif 'OLLAMA_PORT:-11434' in host_port:
local_ports.append('11434')
print(f"β
Local default ports: {', '.join(local_ports)}")
# Check modal ports
with open("docker-compose.modal.yml", 'r') as f:
modal_config = yaml.safe_load(f)
modal_ports = []
for service_name, service_config in modal_config['services'].items():
ports = service_config.get('ports', [])
for port_mapping in ports:
if isinstance(port_mapping, str):
host_port = port_mapping.split(':')[0]
if 'GRADIO_PORT:-7860' in host_port:
modal_ports.append('7860')
elif 'A2A_API_PORT:-8000' in host_port:
modal_ports.append('8000')
print(f"β
Modal default ports: {', '.join(modal_ports)}")
return True
except Exception as e:
print(f"β Port configuration test failed: {e}")
return False
def test_compose_validation():
"""Test Docker Compose file validation using docker-compose"""
print("\nπ Testing Docker Compose validation...")
compose_files = [
"docker-compose.local.yml",
"docker-compose.modal.yml"
]
for compose_file in compose_files:
try:
# Test compose file validation
result = subprocess.run([
"docker-compose", "-f", compose_file, "config"
], capture_output=True, text=True, timeout=30)
if result.returncode == 0:
print(f"β
{compose_file} validates with docker-compose")
else:
print(f"β {compose_file} validation failed: {result.stderr}")
return False
except subprocess.TimeoutExpired:
print(f"β οΈ {compose_file} validation timeout (docker-compose not available)")
except FileNotFoundError:
print(f"β οΈ docker-compose not found, skipping validation for {compose_file}")
except Exception as e:
print(f"β οΈ {compose_file} validation error: {e}")
return True
def test_health_check_definitions():
"""Test that health checks are properly defined"""
print("\nπ Testing health check definitions...")
try:
# Test local health checks
with open("docker-compose.local.yml", 'r') as f:
local_config = yaml.safe_load(f)
services_with_healthcheck = []
for service_name, service_config in local_config['services'].items():
if 'healthcheck' in service_config:
healthcheck = service_config['healthcheck']
if 'test' in healthcheck:
services_with_healthcheck.append(service_name)
print(f"β
Local services with health checks: {', '.join(services_with_healthcheck)}")
# Test modal health checks
with open("docker-compose.modal.yml", 'r') as f:
modal_config = yaml.safe_load(f)
modal_healthchecks = []
for service_name, service_config in modal_config['services'].items():
if 'healthcheck' in service_config:
modal_healthchecks.append(service_name)
print(f"β
Modal services with health checks: {', '.join(modal_healthchecks)}")
return True
except Exception as e:
print(f"β Health check test failed: {e}")
return False
def main():
"""Run all Docker Compose tests"""
print("π³ Testing Docker Compose Configurations")
print("=" * 50)
tests = [
("YAML Validity", test_compose_file_validity),
("Environment Variables", test_environment_variables),
("Service Definitions", test_compose_services),
("Port Configurations", test_port_configurations),
("Compose Validation", test_compose_validation),
("Health Checks", test_health_check_definitions)
]
results = {}
for test_name, test_func in tests:
try:
result = test_func()
results[test_name] = result
except Exception as e:
print(f"β {test_name} crashed: {e}")
results[test_name] = False
# Summary
print("\n" + "=" * 50)
print("π Docker Compose Test Results")
print("=" * 50)
passed = sum(1 for r in results.values() if r)
total = len(results)
for test_name, result in results.items():
status = "β
PASS" if result else "β FAIL"
print(f"{test_name}: {status}")
print(f"\nOverall: {passed}/{total} tests passed")
if passed == total:
print("\nπ All Docker Compose tests passed!")
print("\nπ Deployment Commands:")
print("π Local: docker-compose -f docker-compose.local.yml up")
print("βοΈ Modal: docker-compose -f docker-compose.modal.yml up")
print("π§ͺ Test Local: docker-compose -f docker-compose.local.yml --profile test up")
print("π Deploy Modal: docker-compose -f docker-compose.modal.yml --profile deploy up")
else:
print("\nβ οΈ Some Docker Compose tests failed.")
return passed == total
if __name__ == "__main__":
# Change to project directory
os.chdir(os.path.dirname(os.path.dirname(__file__)))
success = main()
sys.exit(0 if success else 1) |