feat: complete production workflow migration
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
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"]) == 23
|
||||
assert sum(item.get("enabled", True) for item in payload["schedules"]) == 23
|
||||
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user