from __future__ import annotations import json from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[1] def test_linux_service_supervises_only_the_python_scheduler() -> None: unit = (PROJECT_ROOT / "deploy" / "gyxx-flow.service").read_text( encoding="utf-8" ) folded = unit.casefold() assert ( "ExecStart=/opt/gyxx-flow/.venv/bin/python -m gyxx_flow schedule run" in unit ) assert "Environment=GYXX_DATA_ROOT=/var/lib/gyxx-flow" in unit assert "Restart=on-failure" in unit assert "OnCalendar=" not in unit assert "schtasks" not in folded assert "cron" not in folded def test_legacy_windows_service_is_only_a_process_supervisor() -> None: installer = (PROJECT_ROOT / "deploy" / "windows-service" / "install.ps1").read_text( encoding="utf-8" ) folded = installer.casefold() assert "schedule run" in installer assert "nssm" in folded assert "schtasks" not in folded assert "new-scheduledtask" not in folded assert "schedule plan" not in folded def test_deployment_documents_one_scheduler_and_external_data_root() -> None: guide = (PROJECT_ROOT / "docs" / "deployment.md").read_text(encoding="utf-8") payload = json.loads( (PROJECT_ROOT / "config" / "schedules.json").read_text(encoding="utf-8") ) assert "config/schedules.json" in guide assert "python -m gyxx_flow schedule run" in guide assert "deploy/gyxx-flow.service" in guide assert "GYXX_DATA_ROOT" in guide assert "/var/lib/gyxx-flow" in guide assert "Windows Task Scheduler" in guide assert len(payload["schedules"]) == 29 assert sum(item.get("enabled", True) for item in payload["schedules"]) == 25 def test_three_canonical_documents_cover_architecture_deployment_and_operations() -> None: architecture = (PROJECT_ROOT / "docs" / "architecture.md").read_text( encoding="utf-8" ) deployment = (PROJECT_ROOT / "docs" / "deployment.md").read_text( encoding="utf-8" ) runbook = (PROJECT_ROOT / "docs" / "runbook.md").read_text(encoding="utf-8") assert "LangGraph" in architecture assert "systemd" in deployment assert "故障处理" in runbook def test_postgres_compose_exposes_only_a_loopback_local_database() -> None: compose = (PROJECT_ROOT / "deploy" / "postgres.compose.yml").read_text( encoding="utf-8" ) assert '"127.0.0.1:5432:5432"' in compose assert "POSTGRES_DB: gyxx_super_data" in compose assert "POSTGRES_USER: gyxx_flow" in compose assert "GYXX_POSTGRES_PASSWORD" in compose assert "8.148.185.119" not in compose assert compose.count("/docker-entrypoint-initdb.d/") == 5 content_schema = ( PROJECT_ROOT / "src" / "gyxx_flow" / "modules" / "content_marketing" / "data" / "tools" / "schema_gyxx_super_data.sql" ).read_text(encoding="utf-8") assert "\\c " not in content_schema