from __future__ import annotations from pathlib import Path ROOT = Path(__file__).resolve().parents[2] def test_unraid_template_documents_editable_runtime_settings() -> None: template = (ROOT / "deploy" / "unraid" / "geointel-unraid-template.xml").read_text(encoding="utf-8") assert "geointel" in template assert "GeoIntel all-in-one runs the complete GeoIntel Kempen V1 stack in one Docker container" in template assert "geointel-all-in-one:latest" in template assert "http://[IP]:[PORT:80]/" in template assert "http://192.168.10.150:1202/geointel-icon.png" in template assert 'Target="80"' in template assert 'Target="/app/storage"' in template assert 'Target="/var/lib/postgresql/data"' in template assert 'Target="GEOINTEL_POSTGRES_PASSWORD"' in template assert 'Mask="true">change-me-before-shared-use' in template def test_unraid_env_template_matches_single_container_compose_variables() -> None: compose = (ROOT / "docker-compose.unraid.yml").read_text(encoding="utf-8") env_template = (ROOT / "deploy" / "unraid" / "geointel.env.example").read_text(encoding="utf-8") for key in ( "GEOINTEL_FRONTEND_PORT", "GEOINTEL_STORAGE_PATH", "GEOINTEL_POSTGIS_DATA_PATH", "GEOINTEL_POSTGRES_DB", "GEOINTEL_POSTGRES_USER", "GEOINTEL_POSTGRES_PASSWORD", "GEOINTEL_CORS_ORIGINS", "GEOINTEL_MAX_UPLOAD_MB", ): assert key in compose assert f"{key}=" in env_template assert "GEOINTEL_FRONTEND_PORT=1202" in env_template assert "GEOINTEL_STORAGE_PATH=/mnt/user/appdata/geointel/storage" in env_template assert "GEOINTEL_POSTGIS_DATA_PATH=/mnt/user/appdata/geointel/postgres-data" in env_template assert "${GEOINTEL_POSTGIS_DATA_PATH:-geointel_postgis}:/var/lib/postgresql/data" in compose assert "geointel_postgis:" in compose assert "geointel:" in compose assert "net.unraid.docker.managed: dockerman" in compose assert 'net.unraid.docker.webui: "http://[IP]:[PORT:80]/"' in compose assert 'net.unraid.docker.icon: "/boot/config/plugins/dockerMan/images/geointel-icon.png"' in compose assert "db:" not in compose assert "backend:" not in compose assert "frontend:" not in compose assert '"${GEOINTEL_FRONTEND_PORT:-1202}:80"' in compose def test_unraid_readme_explains_port_changes_and_safe_cleanup() -> None: readme = (ROOT / "deploy" / "unraid" / "README.md").read_text(encoding="utf-8") assert "cp deploy/unraid/geointel.env.example .env" in readme assert "GEOINTEL_FRONTEND_PORT=1203" in readme assert "docker build -f deploy/unraid/Dockerfile.all-in-one -t geointel-all-in-one:latest ." in readme assert "bash deploy/unraid/run-dockerman-container.sh" in readme assert "net.unraid.docker.managed=dockerman" in readme assert "curl -fsS" in readme assert "docker builder prune -af" in readme assert "Avoid broad volume pruning" in readme def test_unraid_all_in_one_runtime_starts_embedded_postgis_backend_and_nginx() -> None: dockerfile = (ROOT / "deploy" / "unraid" / "Dockerfile.all-in-one").read_text(encoding="utf-8") start_script = (ROOT / "deploy" / "unraid" / "all-in-one-start.sh").read_text(encoding="utf-8") dockerman_script = (ROOT / "deploy" / "unraid" / "run-dockerman-container.sh").read_text(encoding="utf-8") nginx_config = (ROOT / "deploy" / "unraid" / "nginx-all-in-one.conf").read_text(encoding="utf-8") dockerignore = (ROOT / ".dockerignore").read_text(encoding="utf-8") assert "FROM postgres:16-bookworm AS runtime" in dockerfile assert "postgresql-16-postgis-3" in dockerfile assert "postgresql-16-postgis-3-scripts" in dockerfile assert "ln -sf /usr/bin/python3.11 /usr/local/bin/python3" in dockerfile assert "ln -sf /usr/bin/python3.11 /usr/bin/python3" in dockerfile assert "/usr/bin/python3.11 -m venv /opt/geointel/venv" in dockerfile assert "python3-pip" not in dockerfile assert "python3-venv" in dockerfile assert "COPY --from=frontend-build /frontend/dist/ /usr/share/nginx/html/" in dockerfile assert "rm -f /etc/nginx/sites-enabled/default" in dockerfile assert "GEOINTEL_POSTGRES_PASSWORD=" not in dockerfile assert "GEOINTEL_POSTGRES_DB=" not in dockerfile assert "GEOINTEL_POSTGRES_USER=" not in dockerfile assert 'GEOINTEL_POSTGRES_PASSWORD="${GEOINTEL_POSTGRES_PASSWORD:-geointel}"' not in start_script assert 'POSTGRES_PASSWORD="${GEOINTEL_POSTGRES_PASSWORD:-${POSTGRES_PASSWORD:-geointel}}"' in start_script assert 'CMD ["/usr/local/bin/geointel-all-in-one-start"]' in dockerfile assert "/usr/local/bin/docker-entrypoint.sh postgres &" in start_script assert "python -m alembic upgrade head" in start_script assert "uvicorn app.main:app --host 127.0.0.1 --port 8000 &" in start_script assert 'exec nginx -g "daemon off;"' in start_script assert "docker run -d" in dockerman_script assert "--label net.unraid.docker.managed=dockerman" in dockerman_script assert "migrate_compose_volume_if_needed" in dockerman_script assert "docker rm -f geointel" in dockerman_script assert "proxy_pass http://127.0.0.1:8000/api/" in nginx_config assert "proxy_pass http://127.0.0.1:8000/health" in nginx_config assert "location = /geointel-icon.png" in nginx_config assert "frontend/node_modules" in dockerignore assert "storage" in dockerignore assert "postgres-data" in dockerignore def test_tower_deploy_uses_single_container_unraid_compose() -> None: powershell = (ROOT / "scripts" / "deploy_tower.ps1").read_text(encoding="utf-8") bash = (ROOT / "scripts" / "deploy_tower.sh").read_text(encoding="utf-8") for script in (powershell, bash): assert "docker compose -f docker-compose.unraid.yml config" in script assert "docker build -f deploy/unraid/Dockerfile.all-in-one -t geointel-all-in-one:latest ." in script assert "docker compose -f docker-compose.unraid.yml build geointel" not in script assert "bash deploy/unraid/run-dockerman-container.sh" in script assert "LIVE_SMOKE_CONTAINER=geointel bash scripts/live_migration_smoke.sh" in script def test_live_migration_smoke_supports_dockerman_native_container() -> None: script = (ROOT / "scripts" / "live_migration_smoke.sh").read_text(encoding="utf-8") assert 'LIVE_SMOKE_CONTAINER="${LIVE_SMOKE_CONTAINER:-}"' in script assert "run_container_smoke()" in script assert 'docker exec -i "$container_name" sh' in script def test_frontend_and_unraid_icon_assets_are_present() -> None: deploy_icon = (ROOT / "deploy" / "unraid" / "geointel-icon.svg").read_text(encoding="utf-8") frontend_icon = (ROOT / "frontend" / "public" / "geointel-icon.svg").read_text(encoding="utf-8") deploy_png = ROOT / "deploy" / "unraid" / "geointel-icon.png" frontend_png = ROOT / "frontend" / "public" / "geointel-icon.png" index = (ROOT / "frontend" / "index.html").read_text(encoding="utf-8") assert " 1000 assert '' in index