mirror of
https://github.com/meshtastic/python.git
synced 2026-06-02 12:45:00 -04:00
tests of new BLEError functionality
This commit is contained in:
69
meshtastic/tests/test_ble_interface.py
Normal file
69
meshtastic/tests/test_ble_interface.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""Meshtastic unit tests for ble_interface.py"""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from bleak.exc import BleakError
|
||||
|
||||
from ..ble_interface import BLEInterface
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_ble_error_default_kind_unknown():
|
||||
"""BLEError defaults to UNKNOWN kind."""
|
||||
error = BLEInterface.BLEError("test")
|
||||
assert error.kind == BLEInterface.BLEError.UNKNOWN
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_ble_find_device_not_found_sets_kind():
|
||||
"""find_device emits DEVICE_NOT_FOUND for no scan results."""
|
||||
iface = object.__new__(BLEInterface)
|
||||
with patch("meshtastic.ble_interface.BLEInterface.scan", return_value=[]):
|
||||
with pytest.raises(BLEInterface.BLEError) as excinfo:
|
||||
iface.find_device("missing")
|
||||
assert excinfo.value.kind == BLEInterface.BLEError.DEVICE_NOT_FOUND
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_ble_find_device_multiple_sets_kind():
|
||||
"""find_device emits MULTIPLE_DEVICES for ambiguous matches."""
|
||||
iface = object.__new__(BLEInterface)
|
||||
first = MagicMock()
|
||||
first.name = "dup"
|
||||
first.address = "AA:AA:AA:AA:AA:01"
|
||||
second = MagicMock()
|
||||
second.name = "dup"
|
||||
second.address = "AA:AA:AA:AA:AA:02"
|
||||
with patch(
|
||||
"meshtastic.ble_interface.BLEInterface.scan", return_value=[first, second]
|
||||
):
|
||||
with pytest.raises(BLEInterface.BLEError) as excinfo:
|
||||
iface.find_device("dup")
|
||||
assert excinfo.value.kind == BLEInterface.BLEError.MULTIPLE_DEVICES
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_ble_send_to_radio_wraps_write_errors_with_kind():
|
||||
"""_sendToRadioImpl wraps write failures with WRITE_ERROR."""
|
||||
iface = object.__new__(BLEInterface)
|
||||
iface.client = MagicMock()
|
||||
iface.client.write_gatt_char.side_effect = RuntimeError("boom")
|
||||
to_radio = MagicMock()
|
||||
to_radio.SerializeToString.return_value = b"\x01"
|
||||
with pytest.raises(BLEInterface.BLEError) as excinfo:
|
||||
iface._sendToRadioImpl(to_radio)
|
||||
assert excinfo.value.kind == BLEInterface.BLEError.WRITE_ERROR
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_ble_receive_wraps_unexpected_bleak_error_with_kind():
|
||||
"""_receiveFromRadioImpl wraps unexpected BleakError with READ_ERROR."""
|
||||
iface = object.__new__(BLEInterface)
|
||||
iface.should_read = True
|
||||
iface._want_receive = True
|
||||
iface.client = MagicMock()
|
||||
iface.client.read_gatt_char.side_effect = BleakError("some other BLE failure")
|
||||
with pytest.raises(BLEInterface.BLEError) as excinfo:
|
||||
iface._receiveFromRadioImpl()
|
||||
assert excinfo.value.kind == BLEInterface.BLEError.READ_ERROR
|
||||
@@ -9,6 +9,7 @@ import sys
|
||||
from unittest.mock import mock_open, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
import meshtastic.__main__ as mt_main
|
||||
|
||||
from meshtastic.__main__ import (
|
||||
export_config,
|
||||
@@ -25,6 +26,7 @@ from meshtastic import mt_config
|
||||
from ..protobuf.channel_pb2 import Channel # pylint: disable=E0611
|
||||
|
||||
# from ..ble_interface import BLEInterface
|
||||
from ..mesh_interface import MeshInterface
|
||||
from ..node import Node
|
||||
|
||||
# from ..radioconfig_pb2 import UserPreferences
|
||||
@@ -259,6 +261,113 @@ def test_main_info_with_permission_error(patched_getlogin, capsys, caplog):
|
||||
assert err == ""
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_main_ble_device_not_found_message(capsys):
|
||||
"""Test BLE device-not-found help text."""
|
||||
sys.argv = ["", "--info", "--ble", "any"]
|
||||
mt_config.args = sys.argv
|
||||
|
||||
with patch("meshtastic.__main__.BLEInterface.__init__") as mock_ble_init:
|
||||
mock_ble_init.side_effect = mt_main.BLEInterface.BLEError(
|
||||
"missing",
|
||||
mt_main.BLEInterface.BLEError.DEVICE_NOT_FOUND,
|
||||
)
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main()
|
||||
|
||||
out, err = capsys.readouterr()
|
||||
assert excinfo.value.code == 1
|
||||
assert re.search(r"BLE device not found", out, re.MULTILINE)
|
||||
assert re.search(r"--ble-scan", out, re.MULTILINE)
|
||||
assert err == ""
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_main_ble_multiple_devices_message(capsys):
|
||||
"""Test BLE multiple-devices help text."""
|
||||
sys.argv = ["", "--info", "--ble", "any"]
|
||||
mt_config.args = sys.argv
|
||||
|
||||
with patch("meshtastic.__main__.BLEInterface.__init__") as mock_ble_init:
|
||||
mock_ble_init.side_effect = mt_main.BLEInterface.BLEError(
|
||||
"multiple",
|
||||
mt_main.BLEInterface.BLEError.MULTIPLE_DEVICES,
|
||||
)
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main()
|
||||
|
||||
out, err = capsys.readouterr()
|
||||
assert excinfo.value.code == 1
|
||||
assert re.search(r"Multiple Meshtastic BLE devices found", out, re.MULTILINE)
|
||||
assert re.search(r"meshtastic --ble <name_or_address>", out, re.MULTILINE)
|
||||
assert err == ""
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_main_ble_write_error_message(capsys):
|
||||
"""Test BLE write-error help text."""
|
||||
sys.argv = ["", "--info", "--ble", "any"]
|
||||
mt_config.args = sys.argv
|
||||
|
||||
with patch("meshtastic.__main__.BLEInterface.__init__") as mock_ble_init:
|
||||
mock_ble_init.side_effect = mt_main.BLEInterface.BLEError(
|
||||
"write fail",
|
||||
mt_main.BLEInterface.BLEError.WRITE_ERROR,
|
||||
)
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main()
|
||||
|
||||
out, err = capsys.readouterr()
|
||||
assert excinfo.value.code == 1
|
||||
assert re.search(r"Failed to write to BLE device", out, re.MULTILINE)
|
||||
assert re.search(r"user not in 'bluetooth' group", out, re.MULTILINE)
|
||||
assert err == ""
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_main_ble_read_error_message(capsys):
|
||||
"""Test BLE read-error help text."""
|
||||
sys.argv = ["", "--info", "--ble", "any"]
|
||||
mt_config.args = sys.argv
|
||||
|
||||
with patch("meshtastic.__main__.BLEInterface.__init__") as mock_ble_init:
|
||||
mock_ble_init.side_effect = mt_main.BLEInterface.BLEError(
|
||||
"read fail",
|
||||
mt_main.BLEInterface.BLEError.READ_ERROR,
|
||||
)
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main()
|
||||
|
||||
out, err = capsys.readouterr()
|
||||
assert excinfo.value.code == 1
|
||||
assert re.search(r"Failed to read from BLE device", out, re.MULTILINE)
|
||||
assert re.search(r"Move closer to the device", out, re.MULTILINE)
|
||||
assert err == ""
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_main_serial_timeout_message(capsys):
|
||||
"""Test serial timeout help text."""
|
||||
sys.argv = ["", "--info"]
|
||||
mt_config.args = sys.argv
|
||||
|
||||
with patch("meshtastic.serial_interface.SerialInterface") as mock_serial:
|
||||
mock_serial.side_effect = MeshInterface.MeshInterfaceError("Timed out waiting")
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main()
|
||||
|
||||
out, err = capsys.readouterr()
|
||||
assert excinfo.value.code == 1
|
||||
assert re.search(r"Connection timed out", out, re.MULTILINE)
|
||||
assert re.search(r"Device is rebooting", out, re.MULTILINE)
|
||||
assert err == ""
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.usefixtures("reset_mt_config")
|
||||
def test_main_info_with_tcp_interface(capsys):
|
||||
|
||||
Reference in New Issue
Block a user