summaryrefslogtreecommitdiff
path: root/stacks/daemon/test_daemon_log.py
diff options
context:
space:
mode:
authorinfo@mode42.com <info@mode42.com>2026-08-07 18:23:28 +0000
committerinfo@mode42.com <info@mode42.com>2026-08-07 18:23:28 +0000
commitfa05a5f8238e9e1417235711656e5062ccc843a7 (patch)
tree46fbbd18de54492b59307c16efcc7f3152723238 /stacks/daemon/test_daemon_log.py
Initial push
Diffstat (limited to 'stacks/daemon/test_daemon_log.py')
-rw-r--r--stacks/daemon/test_daemon_log.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/stacks/daemon/test_daemon_log.py b/stacks/daemon/test_daemon_log.py
new file mode 100644
index 0000000..0569ca1
--- /dev/null
+++ b/stacks/daemon/test_daemon_log.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3
+"""Unit tests for max25d structured logging."""
+from __future__ import annotations
+
+import sys
+from pathlib import Path
+
+ROOT = Path(__file__).resolve().parents[2]
+sys.path.insert(0, str(ROOT / "stacks" / "daemon"))
+
+from daemon_log import DaemonLogger, emit_startup_banner # noqa: E402
+from device_backends import DeviceBackendConfig # noqa: E402
+
+
+def test_structured_levels() -> None:
+ lines: list[str] = []
+ log = DaemonLogger(emit=lines.append)
+ log.ok("prep complete", area="serial", device="tnc2c")
+ log.recovery("JHOST 0 — banner", device="pktnc2")
+ log.warn("no password", area="security")
+ assert lines[0] == "max25d [OK] [serial] [tnc2c] prep complete"
+ assert lines[1] == "max25d [RECOVERY] [serial] [pktnc2] JHOST 0 — banner"
+ assert lines[2] == "max25d [WARN] [security] no password"
+
+
+def test_emit_unstructured_device_prefix() -> None:
+ lines: list[str] = []
+ log = DaemonLogger(emit=lines.append)
+ log.emit_unstructured("tnc2c: recovery: OK after JHOST 0")
+ assert "[tnc2c]" in lines[0]
+ assert "[RECOVERY]" in lines[0]
+ assert "OK after JHOST 0" in lines[0]
+
+
+def test_startup_banner_sections() -> None:
+ from dataclasses import dataclass
+
+ @dataclass
+ class Cfg:
+ mode: str = "standalone"
+ device: str = "tnc2c"
+ default_device: str = "tnc2c"
+ tcp_host: str = "127.0.0.1"
+ tcp_port: int = 7325
+ unix_socket: str = "/run/max25/modem.sock"
+ tcp_password: str = ""
+ callerid: str = "CB-0"
+ callid: str = "QST"
+ ax25_ui: bool = True
+ bans_file: str = ""
+ auto_start: bool = True
+ serial_enabled: bool = True
+ stack_recover_only: bool = True
+ serial_watch: bool = True
+ serial_watch_interval: int = 60
+ serial_watch_startup_grace: int = 45
+ serial_bootwait_escalate: bool = True
+ hardware: str = "tncs"
+
+ lines: list[str] = []
+ from daemon_log import LOGGER
+
+ orig = LOGGER._emit
+ try:
+ LOGGER._emit = lines.append
+ dev = DeviceBackendConfig(device_id="tnc2c", backend_type="kiss-serial")
+ dev.serial_device = "/dev/ttyS4"
+ dev.serial_baud = 19200
+ dev.serial_line = "8n1"
+ emit_startup_banner(
+ config_path="/etc/max25/max25d.ini",
+ cfg=Cfg(),
+ devices=[dev],
+ tested_fn=lambda _d: True,
+ )
+ finally:
+ LOGGER._emit = orig
+
+ text = "\n".join(lines)
+ assert "=== MAX25d starting ===" in text
+ assert "[config]" in text
+ assert "ini=/etc/max25/max25d.ini" in text
+ assert "[devices]" in text
+ assert "tnc2c=" in text
+
+
+def main() -> int:
+ test_structured_levels()
+ print("OK test_structured_levels")
+ test_emit_unstructured_device_prefix()
+ print("OK test_emit_unstructured_device_prefix")
+ test_startup_banner_sections()
+ print("OK test_startup_banner_sections")
+ print("All daemon_log tests passed")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com