ForcePilot/backend/test/unit/channels/contract/dtos/test_health.py
Kris 08617091dc refactor: 整理项目包结构与导入路径
- 新增多个业务域的__init__.py模块文件,规范包导出结构
- 调整多个DTO文件的导入路径,统一模块组织方式
- 移除测试文件中多余的空行与导入语句
- 优化部分业务模块的包层级划分
2026-07-18 02:04:03 +08:00

196 lines
5.6 KiB
Python

"""health.py DTO 单元测试。
覆盖 ``WorkerStatus`` / ``RedisStreamStatus`` / ``ConnectionPoolStatus`` /
``AccountHealthSnapshot`` / ``WorkerHealthSnapshot`` /
``TransportHealthSnapshot`` / ``DegradedComponentDetail`` / ``HealthQuery`` /
``HealthSnapshot`` / ``ChannelHealth`` / ``ProbeResult`` /
``AdapterProbeOutcome`` / ``DiagnosticsExportRequest`` / ``DiagnosticsBundle``
的字段赋值、默认值、不可变语义与 ``__post_init__`` 校验逻辑。
"""
from __future__ import annotations
import dataclasses
from datetime import datetime
import pytest
from yuxi.channels.contract.dtos.health.health import (
AccountHealthSnapshot,
ConnectionPoolStatus,
DiagnosticsBundle,
DiagnosticsExportRequest,
HealthQuery,
HealthSnapshot,
RedisStreamStatus,
TransportHealthSnapshot,
WorkerStatus,
)
from yuxi.channels.contract.dtos.messaging.common import Operator, OperatorRole
from yuxi.channels.contract.errors import ValidationError
pytestmark = pytest.mark.unit
def _make_operator() -> Operator:
return Operator(user_id="admin-1", role=OperatorRole.ADMIN_USER)
@pytest.mark.unit
class TestWorkerStatus:
"""队列 Worker 状态值对象测试。"""
def test_defaults(self):
# Act
status = WorkerStatus(queue_name="default", available=True)
# Assert
assert status.queue_depth == 0
assert status.worker_utilization is None
assert status.summary == ""
@pytest.mark.unit
class TestRedisStreamStatus:
"""Redis 流状态值对象测试。"""
def test_defaults(self):
# Act
status = RedisStreamStatus(available=True, db_size=100)
# Assert
assert status.summary == ""
@pytest.mark.unit
class TestConnectionPoolStatus:
"""数据库连接池状态值对象测试。"""
def test_defaults(self):
# Act
status = ConnectionPoolStatus(available=True)
# Assert
assert status.size == 0
assert status.reason is None
@pytest.mark.unit
class TestAccountHealthSnapshot:
"""传输引擎单账号健康状态值对象测试。"""
def test_fields_are_assigned(self):
# Act
snap = AccountHealthSnapshot(
channel_type="wechat",
account_id="acc-1",
state="running",
last_activity_at=1000.0,
backoff_attempt=0,
consecutive_successes=5,
)
# Assert
assert snap.state == "running"
@pytest.mark.unit
class TestTransportHealthSnapshot:
"""传输引擎健康状态值对象测试。"""
def test_defaults(self):
# Act
snap = TransportHealthSnapshot(running=True)
# Assert
assert snap.puller is None
assert snap.stream is None
@pytest.mark.unit
class TestHealthQuery:
"""健康查询 DTO 测试。"""
def test_defaults(self):
# Act
query = HealthQuery()
# Assert
assert query.channel_filter is None
assert query.with_probe is False
@pytest.mark.unit
class TestHealthSnapshot:
"""健康快照 DTO 测试。"""
def test_defaults(self):
# Act
snap = HealthSnapshot(status="healthy", version="1.0.0")
# Assert
assert snap.degraded_components == ()
assert snap.channels == ()
assert snap.error_code == ""
assert snap.trace_id == ""
assert snap.probed_at is None
def test_is_frozen(self):
# Arrange
snap = HealthSnapshot(status="healthy", version="1.0.0")
# Act / Assert
with pytest.raises(dataclasses.FrozenInstanceError):
snap.status = "unhealthy" # type: ignore[misc]
@pytest.mark.unit
class TestDiagnosticsExportRequest:
"""诊断导出请求 DTO 测试。"""
def test_defaults(self):
# Act
req = DiagnosticsExportRequest(operator=_make_operator())
# Assert
assert req.include_audit_logs is True
assert req.audit_log_count == 100
def test_is_frozen(self):
# Arrange
req = DiagnosticsExportRequest(operator=_make_operator())
# Act / Assert
with pytest.raises(dataclasses.FrozenInstanceError):
req.audit_log_count = 50 # type: ignore[misc]
def test_zero_audit_log_count_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
DiagnosticsExportRequest(operator=_make_operator(), audit_log_count=0)
assert exc_info.value.field == "audit_log_count"
def test_excessive_audit_log_count_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
DiagnosticsExportRequest(operator=_make_operator(), audit_log_count=501)
assert exc_info.value.field == "audit_log_count"
def test_zero_error_log_count_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
DiagnosticsExportRequest(operator=_make_operator(), error_log_count=0)
assert exc_info.value.field == "error_log_count"
def test_excessive_error_log_count_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
DiagnosticsExportRequest(operator=_make_operator(), error_log_count=501)
assert exc_info.value.field == "error_log_count"
@pytest.mark.unit
class TestDiagnosticsBundle:
"""诊断包 DTO 测试。"""
def test_defaults(self):
# Act
bundle = DiagnosticsBundle(
manifest_snapshot={},
plugin_states={},
exported_at=datetime(2024, 1, 1),
)
# Assert
assert bundle.audit_logs == ()
assert bundle.queue_depth == 0
assert bundle.worker_status is None