Files
full-stack-fastapi/backend/tests/mqtt/test_parser_worker.py
魏风 e8846f4831
All checks were successful
Deploy to Production / deploy (push) Successful in 4m55s
refactor: simplify mqtt pipeline state and remove event table
2026-03-19 22:23:36 +08:00

88 lines
2.8 KiB
Python

from sqlmodel import Session, SQLModel, create_engine
from app.models import TerminalDeviceState, TerminalMessageRaw
from app.mqtt.parser_worker import process_pending_batch
from app.mqtt.repository import insert_raw_message
def _session() -> Session:
engine = create_engine("sqlite://")
SQLModel.metadata.create_all(engine)
return Session(engine)
def test_insert_raw_message_sets_unparsed_defaults() -> None:
with _session() as session:
row = insert_raw_message(
session=session,
device_id="device-001",
topic="terminal/device-001/raw",
payload=b"$GPRMC,123520,A,3723.2475,N,12158.3416,W,0.13,309.62,120598,,,A*74\r\n",
qos=1,
retain=False,
)
assert row.parsed_at is None
assert row.parse_error is None
assert row.payload_size > 0
assert len(row.payload_sha256) == 64
def test_worker_marks_success_and_updates_state() -> None:
with _session() as session:
raw = insert_raw_message(
session=session,
device_id="device-001",
topic="terminal/device-001/raw",
payload=b"$GPGGA,123519,3723.2475,N,12158.3416,W,1,12,0.8,10.0,M,-25.0,M,,*65\r\n",
qos=1,
retain=False,
)
processed = process_pending_batch(session=session, batch_size=10)
assert processed == 1
refreshed = session.get(TerminalMessageRaw, raw.id)
assert refreshed is not None
assert refreshed.parsed_at is not None
assert refreshed.parse_error is None
state = session.get(TerminalDeviceState, "device-001")
assert state is not None
assert state.lat is not None
assert state.lon is not None
def test_worker_marks_failed_without_retry_schedule(monkeypatch) -> None:
def _raise_parse_error(_payload: bytes) -> list[dict[str, object]]:
raise ValueError("boom")
monkeypatch.setattr(
"app.mqtt.parser_worker.parse_mixed_payload", _raise_parse_error
)
with _session() as session:
raw = insert_raw_message(
session=session,
device_id="device-err",
topic="terminal/device-err/raw",
payload=b"$GPGGA,broken*00\r\n",
qos=1,
retain=False,
)
processed = process_pending_batch(session=session, batch_size=10)
assert processed == 1
refreshed = session.get(TerminalMessageRaw, raw.id)
assert refreshed is not None
assert refreshed.parsed_at is not None
assert refreshed.parse_error == "boom"
processed_again = process_pending_batch(session=session, batch_size=10)
assert processed_again == 0
def test_schema_excludes_terminal_observation_event_table() -> None:
assert "terminal_observation_event" not in SQLModel.metadata.tables