fix(api): delegate production bootstrap ddl
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m42s
CD Pipeline / build-and-deploy (push) Failing after 11m22s
CD Pipeline / post-deploy-checks (push) Has been skipped
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m42s
CD Pipeline / build-and-deploy (push) Failing after 11m22s
CD Pipeline / post-deploy-checks (push) Has been skipped
This commit is contained in:
@@ -84,6 +84,88 @@ def test_production_worker_delegates_bootstrap_ddl_to_cd() -> None:
|
||||
assert 'owner="cd_migration_preflight"' in source
|
||||
|
||||
|
||||
def test_production_api_delegates_bootstrap_ddl_to_cd() -> None:
|
||||
from src import main as api_main
|
||||
|
||||
root = Path(__file__).resolve().parents[3]
|
||||
documents = yaml.safe_load_all(
|
||||
(root / "k8s/awoooi-prod/06-deployment-api.yaml").read_text(encoding="utf-8")
|
||||
)
|
||||
manifest = next(
|
||||
document for document in documents if document.get("kind") == "Deployment"
|
||||
)
|
||||
container = manifest["spec"]["template"]["spec"]["containers"][0]
|
||||
env = {item["name"]: item.get("value") for item in container["env"]}
|
||||
source = inspect.getsource(api_main.initialize_api_database)
|
||||
|
||||
assert (
|
||||
type(api_main.settings).model_fields["DATABASE_BOOTSTRAP_DDL_ENABLED"].default
|
||||
is True
|
||||
)
|
||||
assert env["DATABASE_BOOTSTRAP_DDL_ENABLED"] == "false"
|
||||
assert "if not settings.DATABASE_BOOTSTRAP_DDL_ENABLED" in source
|
||||
assert 'owner="cd_migration_preflight"' in source
|
||||
assert 'workload="api"' in source
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_database_bootstrap_runs_when_enabled(monkeypatch) -> None:
|
||||
from src import main as api_main
|
||||
|
||||
calls: list[str] = []
|
||||
logs: list[tuple[str, dict[str, object]]] = []
|
||||
|
||||
async def fake_init_db() -> None:
|
||||
calls.append("init_db")
|
||||
|
||||
class _FakeLogger:
|
||||
def info(self, event: str, **fields: object) -> None:
|
||||
logs.append((event, fields))
|
||||
|
||||
monkeypatch.setattr(api_main.settings, "DATABASE_BOOTSTRAP_DDL_ENABLED", True)
|
||||
monkeypatch.setattr(
|
||||
api_main.settings,
|
||||
"DATABASE_URL",
|
||||
"postgresql+asyncpg://test:test@127.0.0.1/test",
|
||||
)
|
||||
monkeypatch.setattr(api_main, "init_db", fake_init_db)
|
||||
monkeypatch.setattr(api_main, "logger", _FakeLogger())
|
||||
|
||||
assert await api_main.initialize_api_database() is True
|
||||
assert calls == ["init_db"]
|
||||
assert logs == [("database_initialized", {"url": "127.0.0.1/test"})]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_database_bootstrap_skips_with_cd_owner_receipt(monkeypatch) -> None:
|
||||
from src import main as api_main
|
||||
|
||||
logs: list[tuple[str, dict[str, object]]] = []
|
||||
|
||||
async def fail_if_called() -> None:
|
||||
raise AssertionError("production API must not execute bootstrap DDL")
|
||||
|
||||
class _FakeLogger:
|
||||
def info(self, event: str, **fields: object) -> None:
|
||||
logs.append((event, fields))
|
||||
|
||||
monkeypatch.setattr(api_main.settings, "DATABASE_BOOTSTRAP_DDL_ENABLED", False)
|
||||
monkeypatch.setattr(api_main, "init_db", fail_if_called)
|
||||
monkeypatch.setattr(api_main, "logger", _FakeLogger())
|
||||
|
||||
assert await api_main.initialize_api_database() is False
|
||||
assert logs == [
|
||||
(
|
||||
"database_bootstrap_ddl_skipped",
|
||||
{
|
||||
"owner": "cd_migration_preflight",
|
||||
"workload": "api",
|
||||
"reason": "database_bootstrap_ddl_disabled",
|
||||
},
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def test_get_engine_uses_database_pool_budget(monkeypatch):
|
||||
from src.db import base as db_base
|
||||
|
||||
|
||||
Reference in New Issue
Block a user