From 615dab049052f4dcb764292a02bc3337f8429fcc Mon Sep 17 00:00:00 2001 From: guke Date: Wed, 8 Jul 2026 17:14:29 +0800 Subject: [PATCH] test(analytics): cover selfstat 503 guard + document empty-events divergence --- app/schemas/analytics_selfstat.py | 2 ++ tests/test_analytics_selfstat.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/app/schemas/analytics_selfstat.py b/app/schemas/analytics_selfstat.py index dea8be7..6edf545 100644 --- a/app/schemas/analytics_selfstat.py +++ b/app/schemas/analytics_selfstat.py @@ -24,6 +24,8 @@ class SelfStatBatchIn(BaseModel): batches_fail: int = 0 retries: int = 0 queue_depth: int = 0 + # 允许空列表:某次快照只上报设备级计数(batches_*/retries/queue_depth)、无 event 细分时也合法 + # (与 AnalyticsBatchIn 的 min_length=1 有意不同——那是行为事件、必须至少一条)。 events: list[SelfStatEventIn] = Field(default_factory=list, max_length=200) diff --git a/tests/test_analytics_selfstat.py b/tests/test_analytics_selfstat.py index 4319f60..a096806 100644 --- a/tests/test_analytics_selfstat.py +++ b/tests/test_analytics_selfstat.py @@ -31,3 +31,13 @@ def test_selfstat_ingest_empty_events(client: TestClient) -> None: r = client.post("/api/v1/analytics/selfstat", json=_payload(events=[])) assert r.status_code == 200, r.text assert r.json()["ok"] is True + + +def test_selfstat_ingest_db_error_returns_503(client: TestClient, monkeypatch) -> None: + """落库异常时端点回 503(计数链路稳定性守卫),不裸奔 500。""" + def _boom(*_args, **_kwargs): + raise RuntimeError("db gone") + + monkeypatch.setattr("app.repositories.analytics_selfstat.record_selfstat", _boom) + r = client.post("/api/v1/analytics/selfstat", json=_payload()) + assert r.status_code == 503, r.text