feat: implement mqtt ingestion, parsing, and archive pipeline

This commit is contained in:
魏风
2026-03-17 13:27:39 +08:00
parent 27101e9bff
commit f02d324335
16 changed files with 896 additions and 5 deletions

View File

@@ -0,0 +1,54 @@
from datetime import timedelta
from pathlib import Path
from sqlmodel import Session, SQLModel, create_engine, select
from app.models import TerminalMessageRaw, get_datetime_utc
from app.mqtt.archive_job import run_archive_once
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_archive_writes_raw_bytes_and_manifest(tmp_path: Path) -> None:
with _session() as session:
current = get_datetime_utc()
old_ts = current - timedelta(days=91)
insert_raw_message(
session=session,
device_id="device-001",
topic="terminal/device-001/raw",
payload=b"abc",
qos=1,
retain=False,
received_at=old_ts,
)
insert_raw_message(
session=session,
device_id="device-001",
topic="terminal/device-001/raw",
payload=b"\x01\x02",
qos=1,
retain=False,
received_at=old_ts,
)
manifests = run_archive_once(
session=session,
archive_base_dir=tmp_path,
retention_days=90,
now=current,
)
assert len(manifests) == 1
archived_file = Path(manifests[0].file_path)
assert archived_file.exists()
assert archived_file.read_bytes() == b"abc\x01\x02"
remaining = session.exec(select(TerminalMessageRaw)).all()
assert remaining == []