from pathlib import Path import re ROOT = Path(__file__).resolve().parents[1] DOCKER_COMPOSE = ROOT / "docker-compose.yml" def _service_block(compose: str, service_name: str) -> str: match = re.search( rf"^ {re.escape(service_name)}:\n(?P.*?)(?=^ [A-Za-z0-9_-]+:\n|\Z)", compose, flags=re.MULTILINE | re.DOTALL, ) assert match, f"{service_name} service block missing" return match.group("body") def test_momo_app_mounts_gunicorn_config_for_sync_deploys(): compose = DOCKER_COMPOSE.read_text(encoding="utf-8") assert 'command: ["gunicorn", "--config", "gunicorn.conf.py", "app:app"]' in compose assert "- ./gunicorn.conf.py:/app/gunicorn.conf.py:ro" in compose assert "- ./static:/app/static:ro" in compose assert "- ./web/static:/app/web/static:ro" in compose def test_core_runtime_services_keep_memory_limits_and_healthchecks(): compose = DOCKER_COMPOSE.read_text(encoding="utf-8") expected_mem_limits = { "momo-app": "mem_limit: 2g", "scheduler": "mem_limit: 2g", "telegram-bot": "mem_limit: 512m", } for service_name, expected_mem_limit in expected_mem_limits.items(): block = _service_block(compose, service_name) assert expected_mem_limit in block assert "healthcheck:" in block assert 'curl", "-f", "http://localhost:80/health"' in _service_block(compose, "momo-app") def test_optional_compose_services_stay_behind_profiles(): compose = DOCKER_COMPOSE.read_text(encoding="utf-8") expected_profiles = { "nginx": "- local-dev", "nginx-monitor": "- deprecated", "metabase": "- bi", "grist": "- bi", } for service_name, profile_line in expected_profiles.items(): block = _service_block(compose, service_name) assert "profiles:" in block assert profile_line in block