summaryrefslogtreecommitdiff
path: root/stacks/daemon/test_baycom_backend.py
diff options
context:
space:
mode:
Diffstat (limited to 'stacks/daemon/test_baycom_backend.py')
-rw-r--r--stacks/daemon/test_baycom_backend.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/stacks/daemon/test_baycom_backend.py b/stacks/daemon/test_baycom_backend.py
new file mode 100644
index 0000000..ebff5a4
--- /dev/null
+++ b/stacks/daemon/test_baycom_backend.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python3
+"""Offline unit tests for BayComKissBackend (no kernel hardware)."""
+from __future__ import annotations
+
+import os
+import sys
+from pathlib import Path
+from unittest.mock import patch
+
+ROOT = Path(__file__).resolve().parents[2]
+sys.path.insert(0, str(ROOT / "stacks" / "daemon"))
+
+from device_backends import BayComKissBackend, DeviceBackendConfig # noqa: E402
+from ax25_codec import ax25_build_ui, ax25_parse_ui # noqa: E402
+from kiss_bridge import KissDecoder, format_rx_line, kiss_data_frame # noqa: E402
+
+
+def test_baycom_kiss_default_link() -> None:
+ cfg = DeviceBackendConfig(device_id="baycom-ser12", backend_type="baycom-kiss", baycom_modem="a")
+ backend = BayComKissBackend(cfg, on_rx=lambda _l: None)
+ assert backend._path in ("/var/run/baycom-pr/kiss", f"/var/run/baycom-pr/kiss-a")
+ assert backend.backend_type == "baycom-kiss"
+ assert backend._is_pty is True
+
+
+def test_baycom_kiss_transmit_kiss_frame() -> None:
+ cfg = DeviceBackendConfig(
+ device_id="baycom-ser12",
+ backend_type="baycom-kiss",
+ kiss_link="/var/run/baycom-pr/kiss",
+ )
+ backend = BayComKissBackend(cfg, on_rx=lambda _l: None)
+ backend._fd = 99
+ backend._kiss_active = True
+ written: list[bytes] = []
+
+ with patch("os.write", side_effect=lambda _fd, data: written.append(data) or len(data)):
+ with patch("termios.tcdrain"):
+ ok, display = backend.transmit("CB-0", "QST", "hello", ax25_ui=True)
+ assert ok, display
+ assert written and written[0].startswith(b"\xc0")
+ assert "hello" in display
+
+
+def test_baycom_kiss_rx_decode_path() -> None:
+ """RX path: KISS bytes → AX.25 UI → on_rx line (same decoder as _rx_loop)."""
+ rx_lines: list[str] = []
+ frame = ax25_build_ui("REMOTE-0", "CB-0", b"73")
+ pkt = kiss_data_frame(0, frame)
+ decoder = KissDecoder()
+ for _port, payload in decoder.feed(pkt):
+ parsed = ax25_parse_ui(payload)
+ assert parsed is not None
+ src, dst, info = parsed
+ assert src == "REMOTE"
+ assert dst == "CB"
+ assert info == b"73"
+ from kiss_bridge import format_rx_line
+
+ rx_lines.append(format_rx_line(src, dst, info, ax25_ui=True))
+ assert rx_lines and "73" in rx_lines[0]
+
+
+def test_baycom_kiss_modem_b_link() -> None:
+ cfg = DeviceBackendConfig(
+ device_id="baycom-b",
+ backend_type="baycom-kiss",
+ baycom_modem="b",
+ kiss_link="/var/run/baycom-pr/kiss-b",
+ )
+ backend = BayComKissBackend(cfg, on_rx=lambda _l: None)
+ assert backend._path == "/var/run/baycom-pr/kiss-b"
+
+
+def test_baycom_kiss_open_missing_path() -> None:
+ backend = BayComKissBackend(
+ DeviceBackendConfig(device_id="baycom-ser12", kiss_link="/nonexistent/kiss/path"),
+ on_rx=lambda _l: None,
+ )
+ assert not backend.open()
+ assert backend.status == "error-no-device"
+
+
+def main() -> int:
+ test_baycom_kiss_default_link()
+ test_baycom_kiss_modem_b_link()
+ test_baycom_kiss_transmit_kiss_frame()
+ test_baycom_kiss_rx_decode_path()
+ test_baycom_kiss_open_missing_path()
+ print("OK: baycom backend tests")
+ 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