refactor web pagination and add partitioned events, flap/timeout showcase agents
This commit is contained in:
@@ -5,7 +5,7 @@ import pytest
|
||||
from sqlalchemy import func, select, update
|
||||
from sqlalchemy.ext.asyncio import async_sessionmaker
|
||||
|
||||
from monlet_server.models import Agent, Event, Incident, NotificationOutbox
|
||||
from monlet_server.models import Agent, Check, Event, Incident, NotificationOutbox
|
||||
from monlet_server.services.detector import LIVENESS_CHECK_ID, _tick
|
||||
from monlet_server.settings import reset_settings_cache
|
||||
|
||||
@@ -82,22 +82,75 @@ async def test_detector_transitions(app_client, auth_headers, engine, session):
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_detector_prunes_bounded_history(
|
||||
app_client, auth_headers, engine, session, monkeypatch
|
||||
):
|
||||
monkeypatch.setenv("MONLET_EVENTS_RETENTION_MAX_ROWS", "2")
|
||||
async def test_detector_owns_liveness_check_and_events(app_client, auth_headers, engine, session):
|
||||
await app_client.post(
|
||||
"/api/v1/heartbeat", json=make_heartbeat("agent-flap"), headers=auth_headers
|
||||
)
|
||||
sm = async_sessionmaker(engine, expire_on_commit=False)
|
||||
|
||||
# Tick 1: alive → Check exists with status=ok, one event.
|
||||
await _tick(sm)
|
||||
session.expire_all()
|
||||
check = (
|
||||
await session.execute(
|
||||
select(Check).where(Check.agent_id == "agent-flap", Check.check_id == LIVENESS_CHECK_ID)
|
||||
)
|
||||
).scalar_one()
|
||||
assert check.status == "ok"
|
||||
n_events = (
|
||||
await session.execute(
|
||||
select(func.count())
|
||||
.select_from(Event)
|
||||
.where(Event.agent_id == "agent-flap", Event.check_id == LIVENESS_CHECK_ID)
|
||||
)
|
||||
).scalar_one()
|
||||
assert n_events == 1
|
||||
|
||||
# Tick 2: still alive → no new event.
|
||||
await _tick(sm)
|
||||
session.expire_all()
|
||||
n_events = (
|
||||
await session.execute(
|
||||
select(func.count())
|
||||
.select_from(Event)
|
||||
.where(Event.agent_id == "agent-flap", Event.check_id == LIVENESS_CHECK_ID)
|
||||
)
|
||||
).scalar_one()
|
||||
assert n_events == 1
|
||||
|
||||
# Push agent into dead → transition event written, Check updates.
|
||||
await session.execute(
|
||||
update(Agent)
|
||||
.where(Agent.agent_id == "agent-flap")
|
||||
.values(last_seen_at=datetime.now(UTC) - timedelta(minutes=10))
|
||||
)
|
||||
await session.commit()
|
||||
await _tick(sm)
|
||||
session.expire_all()
|
||||
check = (
|
||||
await session.execute(
|
||||
select(Check).where(Check.agent_id == "agent-flap", Check.check_id == LIVENESS_CHECK_ID)
|
||||
)
|
||||
).scalar_one()
|
||||
assert check.status == "critical"
|
||||
n_events = (
|
||||
await session.execute(
|
||||
select(func.count())
|
||||
.select_from(Event)
|
||||
.where(Event.agent_id == "agent-flap", Event.check_id == LIVENESS_CHECK_ID)
|
||||
)
|
||||
).scalar_one()
|
||||
assert n_events == 2
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_detector_prunes_outbox(app_client, auth_headers, engine, session, monkeypatch):
|
||||
monkeypatch.setenv("MONLET_OUTBOX_RETENTION_MAX_ROWS", "2")
|
||||
reset_settings_cache()
|
||||
try:
|
||||
await app_client.post(
|
||||
"/api/v1/heartbeat", json=make_heartbeat("agent-prune"), headers=auth_headers
|
||||
)
|
||||
events = [make_event(check_id="prune_check") for _ in range(5)]
|
||||
await app_client.post(
|
||||
"/api/v1/events",
|
||||
json={"agent_id": "agent-prune", "events": events},
|
||||
headers=auth_headers,
|
||||
)
|
||||
critical = make_event(check_id="critical_prune", status="critical", exit_code=2)
|
||||
await app_client.post(
|
||||
"/api/v1/events",
|
||||
@@ -129,7 +182,6 @@ async def test_detector_prunes_bounded_history(
|
||||
sm = async_sessionmaker(engine, expire_on_commit=False)
|
||||
await _tick(sm)
|
||||
|
||||
assert (await session.execute(select(func.count()).select_from(Event))).scalar_one() == 2
|
||||
terminal_outbox = (
|
||||
await session.execute(
|
||||
select(func.count())
|
||||
|
||||
Reference in New Issue
Block a user