Files
Nexus/tests/test_server_metrics.py
T

136 lines
4.1 KiB
Python
Raw Normal View History

"""Per-server metric samples, offline segments, and API."""
from datetime import datetime, timedelta, timezone
import pytest
from server.utils.server_metrics import (
merge_offline_segments,
parse_system_info_metrics,
sample_from_redis_heartbeat,
)
def test_parse_system_info_metrics():
cpu, mem = parse_system_info_metrics({"cpu_usage": 12.4, "mem_usage": 55.6})
assert cpu == 12
assert mem == 56
def test_sample_from_redis_online():
is_online, cpu, mem = sample_from_redis_heartbeat(
{"is_online": "True", "system_info": '{"cpu_usage": 20, "mem_usage": 30}'}
)
assert is_online is True
assert cpu == 20
assert mem == 30
def test_sample_from_redis_offline():
is_online, cpu, mem = sample_from_redis_heartbeat(
{"is_online": "False", "system_info": '{"cpu_usage": 99, "mem_usage": 99}'}
)
assert is_online is False
assert cpu is None
assert mem is None
def test_merge_offline_segments():
points = [
{"recorded_at": "2026-06-09 10:00:00", "is_online": True},
{"recorded_at": "2026-06-09 10:10:00", "is_online": False},
{"recorded_at": "2026-06-09 10:20:00", "is_online": False},
{"recorded_at": "2026-06-09 10:30:00", "is_online": True},
]
segs = merge_offline_segments(points)
assert len(segs) == 1
assert segs[0]["from"] == "2026-06-09 10:10:00"
assert segs[0]["to"] == "2026-06-09 10:20:00"
def test_merge_offline_segments_trailing_offline():
points = [
{"recorded_at": "2026-06-09 10:00:00", "is_online": True},
{"recorded_at": "2026-06-09 10:10:00", "is_online": False},
]
segs = merge_offline_segments(points)
assert len(segs) == 1
assert segs[0]["to"] == "2026-06-09 10:10:00"
@pytest.mark.asyncio
async def test_server_metrics_api(db_session, test_admin):
from server.api.servers import get_server_metrics
from server.application.services.server_service import ServerService
from server.infrastructure.database.server_metric_repo import ServerMetricRepositoryImpl
from server.infrastructure.database.server_repo import ServerRepositoryImpl
from server.infrastructure.database.sync_log_repo import SyncLogRepositoryImpl
from server.domain.models import Server
server = Server(
name="metric-test",
domain="metric.example.com",
port=22,
agent_version="1.0.0",
)
db_session.add(server)
await db_session.flush()
repo = ServerMetricRepositoryImpl(db_session)
now = datetime.now(timezone.utc)
await repo.insert_sample(
server_id=server.id,
recorded_at=now - timedelta(minutes=20),
is_online=True,
cpu_pct=10,
mem_pct=20,
)
await repo.insert_sample(
server_id=server.id,
recorded_at=now - timedelta(minutes=10),
is_online=False,
cpu_pct=None,
mem_pct=None,
)
await db_session.commit()
service = ServerService(
ServerRepositoryImpl(db_session),
SyncLogRepositoryImpl(db_session),
)
body = await get_server_metrics(
id=server.id,
hours=24,
admin=test_admin["admin"],
service=service,
db=db_session,
)
assert body["server_id"] == server.id
assert body["hours"] == 24
assert body["interval_minutes"] == 10
assert len(body["points"]) >= 2
assert len(body["offline_segments"]) >= 1
@pytest.mark.asyncio
async def test_server_metrics_api_not_found(db_session, test_admin):
from server.api.servers import get_server_metrics
from server.application.services.server_service import ServerService
from server.infrastructure.database.server_repo import ServerRepositoryImpl
from server.infrastructure.database.sync_log_repo import SyncLogRepositoryImpl
from fastapi import HTTPException
service = ServerService(
ServerRepositoryImpl(db_session),
SyncLogRepositoryImpl(db_session),
)
with pytest.raises(HTTPException) as exc:
await get_server_metrics(
id=999999,
hours=24,
admin=test_admin["admin"],
service=service,
db=db_session,
)
assert exc.value.status_code == 404