summaryrefslogtreecommitdiff
path: root/stacks/daemon/test_baycom_backend.py
blob: ebff5a4eabd327514f49214d0c31e0526adba57d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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