88 lines
2.8 KiB
Python
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
|