Module meshtastic.tests.test_main
Meshtastic unit tests for main.py
Expand source code
"""Meshtastic unit tests for __main__.py"""
# pylint: disable=C0302,W0613,R0917
import logging
import os
import platform
import re
import sys
from unittest.mock import mock_open, MagicMock, patch
import pytest
from meshtastic.__main__ import (
export_config,
initParser,
main,
onConnection,
onNode,
onReceive,
tunnelMain,
)
from meshtastic import mt_config
from ..protobuf.channel_pb2 import Channel # pylint: disable=E0611
# from ..ble_interface import BLEInterface
from ..node import Node
# from ..radioconfig_pb2 import UserPreferences
# import meshtastic.config_pb2
from ..serial_interface import SerialInterface
from ..tcp_interface import TCPInterface
# from ..remote_hardware import onGPIOreceive
# from ..config_pb2 import Config
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_init_parser_no_args(capsys):
"""Test no arguments"""
sys.argv = [""]
mt_config.args = sys.argv
initParser()
out, err = capsys.readouterr()
assert out == ""
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_init_parser_version(capsys):
"""Test --version"""
sys.argv = ["", "--version"]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
initParser()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 0
out, err = capsys.readouterr()
assert re.match(r"[0-9]+\.[0-9]+[\.a][0-9]", out)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_main_version(capsys):
"""Test --version"""
sys.argv = ["", "--version"]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 0
out, err = capsys.readouterr()
assert re.match(r"[0-9]+\.[0-9]+[\.a][0-9]", out)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_main_no_args(capsys):
"""Test with no args"""
sys.argv = [""]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
_, err = capsys.readouterr()
assert re.search(r"usage:", err, re.MULTILINE)
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_support(capsys):
"""Test --support"""
sys.argv = ["", "--support"]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 0
out, err = capsys.readouterr()
assert re.search(r"System", out, re.MULTILINE)
assert re.search(r"Platform", out, re.MULTILINE)
assert re.search(r"Machine", out, re.MULTILINE)
assert re.search(r"Executable", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.util.findPorts", return_value=[])
def test_main_ch_index_no_devices(patched_find_ports, capsys):
"""Test --ch-index 1"""
sys.argv = ["", "--ch-index", "1"]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert mt_config.channel_index == 1
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"No.*Meshtastic.*device.*detected", out, re.MULTILINE)
assert err == ""
patched_find_ports.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.util.findPorts", return_value=[])
def test_main_test_no_ports(patched_find_ports, capsys):
"""Test --test with no hardware"""
sys.argv = ["", "--test"]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
patched_find_ports.assert_called()
out, err = capsys.readouterr()
assert re.search(
r"Warning: Must have at least two devices connected to USB", out, re.MULTILINE
)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyFake1"])
def test_main_test_one_port(patched_find_ports, capsys):
"""Test --test with one fake port"""
sys.argv = ["", "--test"]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
patched_find_ports.assert_called()
out, err = capsys.readouterr()
assert re.search(
r"Warning: Must have at least two devices connected to USB", out, re.MULTILINE
)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.test.testAll", return_value=True)
def test_main_test_two_ports_success(patched_test_all, capsys):
"""Test --test two fake ports and testAll() is a simulated success"""
sys.argv = ["", "--test"]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 0
patched_test_all.assert_called()
out, err = capsys.readouterr()
assert re.search(r"Test was a success.", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.test.testAll", return_value=False)
def test_main_test_two_ports_fails(patched_test_all, capsys):
"""Test --test two fake ports and testAll() is a simulated failure"""
sys.argv = ["", "--test"]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
patched_test_all.assert_called()
out, err = capsys.readouterr()
assert re.search(r"Test was not successful.", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_info(capsys, caplog):
"""Test --info"""
sys.argv = ["", "--info"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
def mock_showInfo():
print("inside mocked showInfo")
iface.showInfo.side_effect = mock_showInfo
with caplog.at_level(logging.DEBUG):
with patch(
"meshtastic.serial_interface.SerialInterface", return_value=iface
) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"inside mocked showInfo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("os.getlogin")
def test_main_info_with_permission_error(patched_getlogin, capsys, caplog):
"""Test --info"""
sys.argv = ["", "--info"]
mt_config.args = sys.argv
patched_getlogin.return_value = "me"
iface = MagicMock(autospec=SerialInterface)
with caplog.at_level(logging.DEBUG):
with pytest.raises(SystemExit) as pytest_wrapped_e:
with patch(
"meshtastic.serial_interface.SerialInterface", return_value=iface
) as mo:
mo.side_effect = PermissionError("bla bla")
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
patched_getlogin.assert_called()
assert re.search(r"Need to add yourself", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_info_with_tcp_interface(capsys):
"""Test --info"""
sys.argv = ["", "--info", "--host", "meshtastic.local"]
mt_config.args = sys.argv
iface = MagicMock(autospec=TCPInterface)
def mock_showInfo():
print("inside mocked showInfo")
iface.showInfo.side_effect = mock_showInfo
with patch("meshtastic.tcp_interface.TCPInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"inside mocked showInfo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_no_proto(capsys):
"""Test --noproto (using --info for output)"""
sys.argv = ["", "--info", "--noproto"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
def mock_showInfo():
print("inside mocked showInfo")
iface.showInfo.side_effect = mock_showInfo
# Override the time.sleep so there is no loop
def my_sleep(amount):
print(f"amount:{amount}")
sys.exit(0)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
with patch("time.sleep", side_effect=my_sleep):
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 0
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"inside mocked showInfo", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_info_with_seriallog_stdout(capsys):
"""Test --info"""
sys.argv = ["", "--info", "--seriallog", "stdout"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
def mock_showInfo():
print("inside mocked showInfo")
iface.showInfo.side_effect = mock_showInfo
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"inside mocked showInfo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_info_with_seriallog_output_txt(capsys):
"""Test --info"""
sys.argv = ["", "--info", "--seriallog", "output.txt"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
def mock_showInfo():
print("inside mocked showInfo")
iface.showInfo.side_effect = mock_showInfo
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"inside mocked showInfo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
# do some cleanup
os.remove("output.txt")
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_qr(capsys):
"""Test --qr"""
sys.argv = ["", "--qr"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
# TODO: could mock/check url
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Primary channel URL", out, re.MULTILINE)
# if a qr code is generated it will have lots of these
assert re.search(r"\[7m", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_onConnected_exception(capsys):
"""Test the exception in onConnected"""
sys.argv = ["", "--qr"]
mt_config.args = sys.argv
def throw_an_exception(junk):
raise Exception("Fake exception.") # pylint: disable=W0719
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
with patch("pyqrcode.create", side_effect=throw_an_exception):
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
out, err = capsys.readouterr()
assert re.search("Aborting due to: Fake exception", out, re.MULTILINE)
assert err == ""
assert pytest_wrapped_e.type == Exception
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_nodes(capsys):
"""Test --nodes"""
sys.argv = ["", "--nodes"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
def mock_showNodes(includeSelf, showFields):
print(f"inside mocked showNodes: {includeSelf} {showFields}")
iface.showNodes.side_effect = mock_showNodes
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"inside mocked showNodes", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_owner_to_bob(capsys):
"""Test --set-owner bob"""
sys.argv = ["", "--set-owner", "bob"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Setting device owner to bob", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_owner_short_to_bob(capsys):
"""Test --set-owner-short bob"""
sys.argv = ["", "--set-owner-short", "bob"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Setting device owner short to bob", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_canned_messages(capsys):
"""Test --set-canned-message"""
sys.argv = ["", "--set-canned-message", "foo"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Setting canned plugin message to foo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_get_canned_messages(capsys, caplog, iface_with_nodes):
"""Test --get-canned-message"""
sys.argv = ["", "--get-canned-message"]
mt_config.args = sys.argv
iface = iface_with_nodes
iface.localNode.cannedPluginMessage = "foo"
iface.devPath = "bar"
with caplog.at_level(logging.DEBUG):
with patch(
"meshtastic.serial_interface.SerialInterface", return_value=iface
) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"canned_plugin_message:foo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_ham_to_KI123(capsys):
"""Test --set-ham KI123"""
sys.argv = ["", "--set-ham", "KI123"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
def mock_turnOffEncryptionOnPrimaryChannel():
print("inside mocked turnOffEncryptionOnPrimaryChannel")
def mock_setOwner(name, is_licensed):
print(f"inside mocked setOwner name:{name} is_licensed:{is_licensed}")
mocked_node.turnOffEncryptionOnPrimaryChannel.side_effect = (
mock_turnOffEncryptionOnPrimaryChannel
)
mocked_node.setOwner.side_effect = mock_setOwner
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Setting Ham ID to KI123", out, re.MULTILINE)
assert re.search(r"inside mocked setOwner", out, re.MULTILINE)
assert re.search(
r"inside mocked turnOffEncryptionOnPrimaryChannel", out, re.MULTILINE
)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_reboot(capsys):
"""Test --reboot"""
sys.argv = ["", "--reboot"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
def mock_reboot():
print("inside mocked reboot")
mocked_node.reboot.side_effect = mock_reboot
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"inside mocked reboot", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_shutdown(capsys):
"""Test --shutdown"""
sys.argv = ["", "--shutdown"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
def mock_shutdown():
print("inside mocked shutdown")
mocked_node.shutdown.side_effect = mock_shutdown
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"inside mocked shutdown", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_sendtext(capsys):
"""Test --sendtext"""
sys.argv = ["", "--sendtext", "hello"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
def mock_sendText(
text, dest, wantAck=False, wantResponse=False, onResponse=None, channelIndex=0, portNum=0
):
print("inside mocked sendText")
print(f"{text} {dest} {wantAck} {wantResponse} {channelIndex} {portNum}")
iface.sendText.side_effect = mock_sendText
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Sending text message", out, re.MULTILINE)
assert re.search(r"inside mocked sendText", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_sendtext_with_channel(capsys):
"""Test --sendtext"""
sys.argv = ["", "--sendtext", "hello", "--ch-index", "1"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
def mock_sendText(
text, dest, wantAck=False, wantResponse=False, onResponse=None, channelIndex=0, portNum=0
):
print("inside mocked sendText")
print(f"{text} {dest} {wantAck} {wantResponse} {channelIndex} {portNum}")
iface.sendText.side_effect = mock_sendText
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Sending text message", out, re.MULTILINE)
assert re.search(r"on channelIndex:1", out, re.MULTILINE)
assert re.search(r"inside mocked sendText", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_sendtext_with_invalid_channel(caplog, capsys):
"""Test --sendtext"""
sys.argv = ["", "--sendtext", "hello", "--ch-index", "-1"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
iface.localNode.getChannelByChannelIndex.return_value = None
with caplog.at_level(logging.DEBUG):
with patch(
"meshtastic.serial_interface.SerialInterface", return_value=iface
) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"is not a valid channel", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_sendtext_with_invalid_channel_nine(caplog, capsys):
"""Test --sendtext"""
sys.argv = ["", "--sendtext", "hello", "--ch-index", "9"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
iface.localNode.getChannelByChannelIndex.return_value = None
with caplog.at_level(logging.DEBUG):
with patch(
"meshtastic.serial_interface.SerialInterface", return_value=iface
) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"is not a valid channel", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_sendtext_with_dest(mock_findPorts, mock_serial, mocked_open, mock_get, mock_set, capsys, caplog, iface_with_nodes):
"""Test --sendtext with --dest"""
sys.argv = ["", "--sendtext", "hello", "--dest", "foo"]
mt_config.args = sys.argv
#iface = iface_with_nodes
#iface.myInfo.my_node_num = 2475227164
serialInterface = SerialInterface(noProto=True)
mocked_channel = MagicMock(autospec=Channel)
serialInterface.localNode.getChannelByChannelIndex = mocked_channel
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface):
with caplog.at_level(logging.DEBUG):
#with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
#assert pytest_wrapped_e.type == SystemExit
#assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert not re.search(
r"Warning: 0 is not a valid channel", out, re.MULTILINE
)
assert not re.search(
r"There is a SECONDARY channel named 'admin'", out, re.MULTILINE
)
print(out)
assert re.search(r"Not sending packet because", caplog.text, re.MULTILINE)
assert re.search(r"Warning: There were no self.nodes.", caplog.text, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_removeposition_remote(capsys):
"""Test --remove-position with a remote dest"""
sys.argv = ["", "--remove-position", "--dest", "!12345678"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Removing fixed position and disabling fixed position setting", out, re.MULTILINE)
assert re.search(r"Waiting for an acknowledgment from remote node", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_setlat_remote(capsys):
"""Test --setlat with a remote dest"""
sys.argv = ["", "--setlat", "37.5", "--dest", "!12345678"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Setting device position and enabling fixed position setting", out, re.MULTILINE)
assert re.search(r"Waiting for an acknowledgment from remote node", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_removeposition(capsys):
"""Test --remove-position"""
sys.argv = ["", "--remove-position"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
def mock_removeFixedPosition():
print("inside mocked removeFixedPosition")
mocked_node.removeFixedPosition.side_effect = mock_removeFixedPosition
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Removing fixed position", out, re.MULTILINE)
assert re.search(r"inside mocked removeFixedPosition", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_setlat(capsys):
"""Test --setlat"""
sys.argv = ["", "--setlat", "37.5"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
def mock_setFixedPosition(lat, lon, alt):
print("inside mocked setFixedPosition")
print(f"{lat} {lon} {alt}")
mocked_node.setFixedPosition.side_effect = mock_setFixedPosition
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Fixing latitude", out, re.MULTILINE)
assert re.search(r"Setting device position", out, re.MULTILINE)
assert re.search(r"inside mocked setFixedPosition", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_setlon(capsys):
"""Test --setlon"""
sys.argv = ["", "--setlon", "-122.1"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
def mock_setFixedPosition(lat, lon, alt):
print("inside mocked setFixedPosition")
print(f"{lat} {lon} {alt}")
mocked_node.setFixedPosition.side_effect = mock_setFixedPosition
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Fixing longitude", out, re.MULTILINE)
assert re.search(r"Setting device position", out, re.MULTILINE)
assert re.search(r"inside mocked setFixedPosition", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_setalt(capsys):
"""Test --setalt"""
sys.argv = ["", "--setalt", "51"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
def mock_setFixedPosition(lat, lon, alt):
print("inside mocked setFixedPosition")
print(f"{lat} {lon} {alt}")
mocked_node.setFixedPosition.side_effect = mock_setFixedPosition
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Fixing altitude", out, re.MULTILINE)
assert re.search(r"Setting device position", out, re.MULTILINE)
assert re.search(r"inside mocked setFixedPosition", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_seturl(capsys):
"""Test --seturl (url used below is what is generated after a factory_reset)"""
sys.argv = ["", "--seturl", "https://www.meshtastic.org/d/#CgUYAyIBAQ"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_valid(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with valid field"""
sys.argv = ["", "--set", "network.wifi_ssid", "foo"]
mt_config.args = sys.argv
serialInterface = SerialInterface(noProto=True)
anode = Node(serialInterface, 1234567890, noProto=True)
serialInterface.localNode = anode
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Set network.wifi_ssid to foo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_valid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with valid field"""
sys.argv = ["", "--set", "network.wifi_psk", "123456789"]
mt_config.args = sys.argv
serialInterface = SerialInterface(noProto=True)
anode = Node(serialInterface, 1234567890, noProto=True)
serialInterface.localNode = anode
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Set network.wifi_psk to 123456789", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_invalid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with an invalid value (psk must be 8 or more characters)"""
sys.argv = ["", "--set", "network.wifi_psk", "1234567"]
mt_config.args = sys.argv
serialInterface = SerialInterface(noProto=True)
anode = Node(serialInterface, 1234567890, noProto=True)
serialInterface.localNode = anode
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert not re.search(r"Set network.wifi_psk to 1234567", out, re.MULTILINE)
assert re.search(
r"Warning: network.wifi_psk must be 8 or more characters.", out, re.MULTILINE
)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_valid_camel_case(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with valid field"""
sys.argv = ["", "--set", "network.wifi_ssid", "foo"]
mt_config.args = sys.argv
mt_config.camel_case = True
serialInterface = SerialInterface(noProto=True)
anode = Node(serialInterface, 1234567890, noProto=True)
serialInterface.localNode = anode
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Set network.wifiSsid to foo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_with_invalid(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with invalid field"""
sys.argv = ["", "--set", "foo", "foo"]
mt_config.args = sys.argv
serialInterface = SerialInterface(noProto=True)
anode = Node(serialInterface, 1234567890, noProto=True)
serialInterface.localNode = anode
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"do not have attribute foo", out, re.MULTILINE)
assert err == ""
mo.assert_called()
# TODO: write some negative --configure tests
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_configure_with_snake_case(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --configure with valid file"""
sys.argv = ["", "--configure", "example_config.yaml"]
mt_config.args = sys.argv
serialInterface = SerialInterface(noProto=True)
anode = Node(serialInterface, 1234567890, noProto=True)
serialInterface.localNode = anode
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
# should these come back? maybe a flag?
#assert re.search(r"Setting device owner", out, re.MULTILINE)
#assert re.search(r"Setting device owner short", out, re.MULTILINE)
#assert re.search(r"Setting channel url", out, re.MULTILINE)
#assert re.search(r"Fixing altitude", out, re.MULTILINE)
#assert re.search(r"Fixing latitude", out, re.MULTILINE)
#assert re.search(r"Fixing longitude", out, re.MULTILINE)
#assert re.search(r"Set location_share to LocEnabled", out, re.MULTILINE)
assert re.search(r"Writing modified configuration to device", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_configure_with_camel_case_keys(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --configure with valid file"""
sys.argv = ["", "--configure", "exampleConfig.yaml"]
mt_config.args = sys.argv
serialInterface = SerialInterface(noProto=True)
anode = Node(serialInterface, 1234567890, noProto=True)
serialInterface.localNode = anode
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
# should these come back? maybe a flag?
#assert re.search(r"Setting device owner", out, re.MULTILINE)
#assert re.search(r"Setting device owner short", out, re.MULTILINE)
#assert re.search(r"Setting channel url", out, re.MULTILINE)
#assert re.search(r"Fixing altitude", out, re.MULTILINE)
#assert re.search(r"Fixing latitude", out, re.MULTILINE)
#assert re.search(r"Fixing longitude", out, re.MULTILINE)
assert re.search(r"Writing modified configuration to device", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_add_valid(capsys):
"""Test --ch-add with valid channel name, and that channel name does not already exist"""
sys.argv = ["", "--ch-add", "testing"]
mt_config.args = sys.argv
mocked_channel = MagicMock(autospec=Channel)
# TODO: figure out how to get it to print the channel name instead of MagicMock
mocked_node = MagicMock(autospec=Node)
# set it up so we do not already have a channel named this
mocked_node.getChannelByName.return_value = False
# set it up so we have free channels
mocked_node.getDisabledChannel.return_value = mocked_channel
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Writing modified channels to device", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_add_invalid_name_too_long(capsys):
"""Test --ch-add with invalid channel name, name too long"""
sys.argv = ["", "--ch-add", "testingtestingtesting"]
mt_config.args = sys.argv
mocked_channel = MagicMock(autospec=Channel)
# TODO: figure out how to get it to print the channel name instead of MagicMock
mocked_node = MagicMock(autospec=Node)
# set it up so we do not already have a channel named this
mocked_node.getChannelByName.return_value = False
# set it up so we have free channels
mocked_node.getDisabledChannel.return_value = mocked_channel
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: Channel name must be shorter", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_add_but_name_already_exists(capsys):
"""Test --ch-add with a channel name that already exists"""
sys.argv = ["", "--ch-add", "testing"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
# set it up so we do not already have a channel named this
mocked_node.getChannelByName.return_value = True
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: This node already has", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_add_but_no_more_channels(capsys):
"""Test --ch-add with but there are no more channels"""
sys.argv = ["", "--ch-add", "testing"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
# set it up so we do not already have a channel named this
mocked_node.getChannelByName.return_value = False
# set it up so we have free channels
mocked_node.getDisabledChannel.return_value = None
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: No free channels were found", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_del(capsys):
"""Test --ch-del with valid secondary channel to be deleted"""
sys.argv = ["", "--ch-del", "--ch-index", "1"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Deleting channel", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_del_no_ch_index_specified(capsys):
"""Test --ch-del without a valid ch-index"""
sys.argv = ["", "--ch-del"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: Need to specify", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_del_primary_channel(capsys):
"""Test --ch-del on ch-index=0"""
sys.argv = ["", "--ch-del", "--ch-index", "0"]
mt_config.args = sys.argv
mt_config.channel_index = 1
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: Cannot delete primary channel", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_enable_valid_secondary_channel(capsys):
"""Test --ch-enable with --ch-index"""
sys.argv = ["", "--ch-enable", "--ch-index", "1"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Writing modified channels", out, re.MULTILINE)
assert err == ""
assert mt_config.channel_index == 1
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_disable_valid_secondary_channel(capsys):
"""Test --ch-disable with --ch-index"""
sys.argv = ["", "--ch-disable", "--ch-index", "1"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Writing modified channels", out, re.MULTILINE)
assert err == ""
assert mt_config.channel_index == 1
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_enable_without_a_ch_index(capsys):
"""Test --ch-enable without --ch-index"""
sys.argv = ["", "--ch-enable"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: Need to specify", out, re.MULTILINE)
assert err == ""
assert mt_config.channel_index is None
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_enable_primary_channel(capsys):
"""Test --ch-enable with --ch-index = 0"""
sys.argv = ["", "--ch-enable", "--ch-index", "0"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: Cannot enable/disable PRIMARY", out, re.MULTILINE)
assert err == ""
assert mt_config.channel_index == 0
mo.assert_called()
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_ch_range_options(capsys):
# """Test changing the various range options."""
# range_options = ['--ch-vlongslow', '--ch-longslow', '--ch-longfast', '--ch-midslow',
# '--ch-midfast', '--ch-shortslow', '--ch-shortfast']
# for range_option in range_options:
# sys.argv = ['', f"{range_option}" ]
# mt_config.args = sys.argv
#
# mocked_node = MagicMock(autospec=Node)
#
# iface = MagicMock(autospec=SerialInterface)
# iface.getNode.return_value = mocked_node
#
# with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
# main()
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'Writing modified channels', out, re.MULTILINE)
# assert err == ''
# mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_longfast_on_non_primary_channel(capsys):
"""Test --ch-longfast --ch-index 1"""
sys.argv = ["", "--ch-longfast", "--ch-index", "1"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: Cannot set modem preset for non-primary channel", out, re.MULTILINE)
assert err == ""
mo.assert_called()
# PositionFlags:
# Misc info that might be helpful (this info will grow stale, just
# a snapshot of the values.) The radioconfig_pb2.PositionFlags.Name and bit values are:
# POS_UNDEFINED 0
# POS_ALTITUDE 1
# POS_ALT_MSL 2
# POS_GEO_SEP 4
# POS_DOP 8
# POS_HVDOP 16
# POS_BATTERY 32
# POS_SATINVIEW 64
# POS_SEQ_NOS 128
# POS_TIMESTAMP 256
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_pos_fields_no_args(capsys):
# """Test --pos-fields no args (which shows settings)"""
# sys.argv = ['', '--pos-fields']
# mt_config.args = sys.argv
#
# pos_flags = MagicMock(autospec=meshtastic.radioconfig_pb2.PositionFlags)
#
# with patch('meshtastic.serial_interface.SerialInterface') as mo:
# mo().getNode().radioConfig.preferences.position_flags = 35
# with patch('meshtastic.radioconfig_pb2.PositionFlags', return_value=pos_flags) as mrc:
#
# mrc.values.return_value = [0, 1, 2, 4, 8, 16, 32, 64, 128, 256]
# # Note: When you use side_effect and a list, each call will use a value from the front of the list then
# # remove that value from the list. If there are three values in the list, we expect it to be called
# # three times.
# mrc.Name.side_effect = ['POS_ALTITUDE', 'POS_ALT_MSL', 'POS_BATTERY']
#
# main()
#
# mrc.Name.assert_called()
# mrc.values.assert_called()
# mo.assert_called()
#
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'POS_ALTITUDE POS_ALT_MSL POS_BATTERY', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_pos_fields_arg_of_zero(capsys):
# """Test --pos-fields an arg of 0 (which shows list)"""
# sys.argv = ['', '--pos-fields', '0']
# mt_config.args = sys.argv
#
# pos_flags = MagicMock(autospec=meshtastic.radioconfig_pb2.PositionFlags)
#
# with patch('meshtastic.serial_interface.SerialInterface') as mo:
# with patch('meshtastic.radioconfig_pb2.PositionFlags', return_value=pos_flags) as mrc:
#
# def throw_value_error_exception(exc):
# raise ValueError()
# mrc.Value.side_effect = throw_value_error_exception
# mrc.keys.return_value = [ 'POS_UNDEFINED', 'POS_ALTITUDE', 'POS_ALT_MSL',
# 'POS_GEO_SEP', 'POS_DOP', 'POS_HVDOP', 'POS_BATTERY',
# 'POS_SATINVIEW', 'POS_SEQ_NOS', 'POS_TIMESTAMP']
#
# main()
#
# mrc.Value.assert_called()
# mrc.keys.assert_called()
# mo.assert_called()
#
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'ERROR: supported position fields are:', out, re.MULTILINE)
# assert re.search(r"['POS_UNDEFINED', 'POS_ALTITUDE', 'POS_ALT_MSL', 'POS_GEO_SEP',"\
# "'POS_DOP', 'POS_HVDOP', 'POS_BATTERY', 'POS_SATINVIEW', 'POS_SEQ_NOS',"\
# "'POS_TIMESTAMP']", out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_pos_fields_valid_values(capsys):
# """Test --pos-fields with valid values"""
# sys.argv = ['', '--pos-fields', 'POS_GEO_SEP', 'POS_ALT_MSL']
# mt_config.args = sys.argv
#
# pos_flags = MagicMock(autospec=meshtastic.radioconfig_pb2.PositionFlags)
#
# with patch('meshtastic.serial_interface.SerialInterface') as mo:
# with patch('meshtastic.radioconfig_pb2.PositionFlags', return_value=pos_flags) as mrc:
#
# mrc.Value.side_effect = [ 4, 2 ]
#
# main()
#
# mrc.Value.assert_called()
# mo.assert_called()
#
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'Setting position fields to 6', out, re.MULTILINE)
# assert re.search(r'Set position_flags to 6', out, re.MULTILINE)
# assert re.search(r'Writing modified preferences to device', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_get_with_valid_values(capsys):
# """Test --get with valid values (with string, number, boolean)"""
# sys.argv = ['', '--get', 'ls_secs', '--get', 'wifi_ssid', '--get', 'fixed_position']
# mt_config.args = sys.argv
#
# with patch('meshtastic.serial_interface.SerialInterface') as mo:
#
# mo().getNode().radioConfig.preferences.wifi_ssid = 'foo'
# mo().getNode().radioConfig.preferences.ls_secs = 300
# mo().getNode().radioConfig.preferences.fixed_position = False
#
# main()
#
# mo.assert_called()
#
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'ls_secs: 300', out, re.MULTILINE)
# assert re.search(r'wifi_ssid: foo', out, re.MULTILINE)
# assert re.search(r'fixed_position: False', out, re.MULTILINE)
# assert err == ''
# TODO
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_get_with_valid_values_camel(capsys, caplog):
# """Test --get with valid values (with string, number, boolean)"""
# sys.argv = ["", "--get", "lsSecs", "--get", "wifiSsid", "--get", "fixedPosition"]
# mt_config.args = sys.argv
# mt_config.camel_case = True
#
# with caplog.at_level(logging.DEBUG):
# with patch("meshtastic.serial_interface.SerialInterface") as mo:
# mo().getNode().radioConfig.preferences.wifi_ssid = "foo"
# mo().getNode().radioConfig.preferences.ls_secs = 300
# mo().getNode().radioConfig.preferences.fixed_position = False
#
# main()
#
# mo.assert_called()
#
# out, err = capsys.readouterr()
# assert re.search(r"Connected to radio", out, re.MULTILINE)
# assert re.search(r"lsSecs: 300", out, re.MULTILINE)
# assert re.search(r"wifiSsid: foo", out, re.MULTILINE)
# assert re.search(r"fixedPosition: False", out, re.MULTILINE)
# assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_get_with_invalid(capsys):
"""Test --get with invalid field"""
sys.argv = ["", "--get", "foo"]
mt_config.args = sys.argv
mocked_user_prefs = MagicMock()
mocked_user_prefs.DESCRIPTOR.fields_by_name.get.return_value = None
mocked_node = MagicMock(autospec=Node)
mocked_node.localConfig = mocked_user_prefs
mocked_node.moduleConfig = mocked_user_prefs
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"do not have attribute foo", out, re.MULTILINE)
assert re.search(r"Choices are...", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_onReceive_empty(caplog, capsys):
"""Test onReceive"""
args = MagicMock()
mt_config.args = args
iface = MagicMock(autospec=SerialInterface)
packet = {}
with caplog.at_level(logging.DEBUG):
onReceive(packet, iface)
assert re.search(r"in onReceive", caplog.text, re.MULTILINE)
out, err = capsys.readouterr()
assert re.search(
r"Warning: Error processing received packet: 'to'.", out, re.MULTILINE
)
assert err == ""
# TODO: use this captured position app message (might want/need in the future)
# packet = {
# 'to': 4294967295,
# 'decoded': {
# 'portnum': 'POSITION_APP',
# 'payload': "M69\306a"
# },
# 'id': 334776976,
# 'hop_limit': 3
# }
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_onReceive_with_sendtext(caplog, capsys):
"""Test onReceive with sendtext
The entire point of this test is to make sure the interface.close() call
is made in onReceive().
"""
sys.argv = ["", "--sendtext", "hello"]
mt_config.args = sys.argv
# Note: 'TEXT_MESSAGE_APP' value is 1
packet = {
"to": 4294967295,
"decoded": {"portnum": 1, "payload": "hello"},
"id": 334776977,
"hop_limit": 3,
"want_ack": True,
}
iface = MagicMock(autospec=SerialInterface)
iface.myInfo.my_node_num = 4294967295
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
with caplog.at_level(logging.DEBUG):
main()
onReceive(packet, iface)
assert re.search(r"in onReceive", caplog.text, re.MULTILINE)
mo.assert_called()
out, err = capsys.readouterr()
assert re.search(r"Sending text message hello to", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_onReceive_with_text(caplog, capsys):
"""Test onReceive with text"""
args = MagicMock()
args.sendtext.return_value = "foo"
mt_config.args = args
# Note: 'TEXT_MESSAGE_APP' value is 1
# Note: Some of this is faked below.
packet = {
"to": 4294967295,
"decoded": {"portnum": 1, "payload": "hello", "text": "faked"},
"id": 334776977,
"hop_limit": 3,
"want_ack": True,
"rxSnr": 6.0,
"hopLimit": 3,
"raw": "faked",
"fromId": "!28b5465c",
"toId": "^all",
}
iface = MagicMock(autospec=SerialInterface)
iface.myInfo.my_node_num = 4294967295
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
with caplog.at_level(logging.DEBUG):
onReceive(packet, iface)
assert re.search(r"in onReceive", caplog.text, re.MULTILINE)
out, err = capsys.readouterr()
assert re.search(r"Sending reply", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_onConnection(capsys):
"""Test onConnection"""
sys.argv = [""]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
class TempTopic:
"""temp class for topic"""
def getName(self):
"""return the fake name of a topic"""
return "foo"
mytopic = TempTopic()
onConnection(iface, mytopic)
out, err = capsys.readouterr()
assert re.search(r"Connection changed: foo", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_export_config(capsys):
"""Test export_config() function directly"""
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
mo.getLongName.return_value = "foo"
mo.getShortName.return_value = "oof"
mo.localNode.getURL.return_value = "bar"
mo.getMyNodeInfo().get.return_value = {
"latitudeI": 1100000000,
"longitudeI": 1200000000,
"altitude": 100,
"batteryLevel": 34,
"latitude": 110.0,
"longitude": 120.0,
}
mo.localNode.radioConfig.preferences = """phone_timeout_secs: 900
ls_secs: 300
position_broadcast_smart: true
fixed_position: true
position_flags: 35"""
export_config(mo)
out, err = capsys.readouterr()
# ensure we do not output this line
assert not re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"owner: foo", out, re.MULTILINE)
assert re.search(r"owner_short: oof", out, re.MULTILINE)
assert re.search(r"channel_url: bar", out, re.MULTILINE)
assert re.search(r"location:", out, re.MULTILINE)
assert re.search(r"lat: 110.0", out, re.MULTILINE)
assert re.search(r"lon: 120.0", out, re.MULTILINE)
assert re.search(r"alt: 100", out, re.MULTILINE)
# TODO: rework above config to test the following
#assert re.search(r"user_prefs:", out, re.MULTILINE)
#assert re.search(r"phone_timeout_secs: 900", out, re.MULTILINE)
#assert re.search(r"ls_secs: 300", out, re.MULTILINE)
#assert re.search(r"position_broadcast_smart: 'true'", out, re.MULTILINE)
#assert re.search(r"fixed_position: 'true'", out, re.MULTILINE)
#assert re.search(r"position_flags: 35", out, re.MULTILINE)
assert err == ""
# TODO
# recursion depth exceeded error
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_export_config_use_camel(capsys):
# """Test export_config() function directly"""
# mt_config.camel_case = True
# iface = MagicMock(autospec=SerialInterface)
# with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
# mo.getLongName.return_value = "foo"
# mo.localNode.getURL.return_value = "bar"
# mo.getMyNodeInfo().get.return_value = {
# "latitudeI": 1100000000,
# "longitudeI": 1200000000,
# "altitude": 100,
# "batteryLevel": 34,
# "latitude": 110.0,
# "longitude": 120.0,
# }
# mo.localNode.radioConfig.preferences = """phone_timeout_secs: 900
#ls_secs: 300
#position_broadcast_smart: true
#fixed_position: true
#position_flags: 35"""
# export_config(mo)
# out, err = capsys.readouterr()
#
# # ensure we do not output this line
# assert not re.search(r"Connected to radio", out, re.MULTILINE)
#
# assert re.search(r"owner: foo", out, re.MULTILINE)
# assert re.search(r"channelUrl: bar", out, re.MULTILINE)
# assert re.search(r"location:", out, re.MULTILINE)
# assert re.search(r"lat: 110.0", out, re.MULTILINE)
# assert re.search(r"lon: 120.0", out, re.MULTILINE)
# assert re.search(r"alt: 100", out, re.MULTILINE)
# assert re.search(r"userPrefs:", out, re.MULTILINE)
# assert re.search(r"phoneTimeoutSecs: 900", out, re.MULTILINE)
# assert re.search(r"lsSecs: 300", out, re.MULTILINE)
# # TODO: should True be capitalized here?
# assert re.search(r"positionBroadcastSmart: 'True'", out, re.MULTILINE)
# assert re.search(r"fixedPosition: 'True'", out, re.MULTILINE)
# assert re.search(r"positionFlags: 35", out, re.MULTILINE)
# assert err == ""
# TODO
# maximum recursion depth error
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_export_config_called_from_main(capsys):
# """Test --export-config"""
# sys.argv = ["", "--export-config"]
# mt_config.args = sys.argv
#
# iface = MagicMock(autospec=SerialInterface)
# with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
# main()
# out, err = capsys.readouterr()
# assert not re.search(r"Connected to radio", out, re.MULTILINE)
# assert re.search(r"# start of Meshtastic configure yaml", out, re.MULTILINE)
# assert err == ""
# mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_gpio_rd_no_gpio_channel(capsys):
"""Test --gpio_rd with no named gpio channel"""
sys.argv = ["", "--gpio-rd", "0x10", "--dest", "!foo"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
iface.localNode.getChannelByName.return_value = None
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Warning: No channel named", out)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_gpio_rd_no_dest(capsys):
"""Test --gpio_rd with a named gpio channel but no dest was specified"""
sys.argv = ["", "--gpio-rd", "0x2000"]
mt_config.args = sys.argv
channel = Channel(index=2, role=2)
channel.settings.psk = b"\x8a\x94y\x0e\xc6\xc9\x1e5\x91\x12@\xa60\xa8\xb43\x87\x00\xf2K\x0e\xe7\x7fAz\xcd\xf5\xb0\x900\xa84"
channel.settings.name = "gpio"
iface = MagicMock(autospec=SerialInterface)
iface.localNode.getChannelByName.return_value = channel
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"Warning: Must use a destination node ID", out)
assert err == ""
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# @patch('time.sleep')
# def test_main_gpio_rd(caplog, capsys):
# """Test --gpio_rd with a named gpio channel"""
# # Note: On the Heltec v2.1, there is a GPIO pin GPIO 13 that does not have a
# # red arrow (meaning ok to use for our purposes)
# # See https://resource.heltec.cn/download/WiFi_LoRa_32/WIFI_LoRa_32_V2.pdf
# # To find out the mask for GPIO 13, let us assign n as 13.
# # 1. Find the 2^n or 2^13 (8192)
# # 2. Convert 8192 decimal to hex (0x2000)
# # You can use python:
# # >>> print(hex(2**13))
# # 0x2000
# sys.argv = ['', '--gpio-rd', '0x1000', '--dest', '!1234']
# mt_config.args = sys.argv
#
# channel = Channel(index=1, role=1)
# channel.settings.modem_config = 3
# channel.settings.psk = b'\x01'
#
# packet = {
#
# 'from': 682968668,
# 'to': 682968612,
# 'channel': 1,
# 'decoded': {
# 'portnum': 'REMOTE_HARDWARE_APP',
# 'payload': b'\x08\x05\x18\x80 ',
# 'requestId': 1629980484,
# 'remotehw': {
# 'typ': 'READ_GPIOS_REPLY',
# 'gpioValue': '4096',
# 'raw': 'faked',
# 'id': 1693085229,
# 'rxTime': 1640294262,
# 'rxSnr': 4.75,
# 'hopLimit': 3,
# 'wantAck': True,
# }
# }
# }
#
# iface = MagicMock(autospec=SerialInterface)
# iface.localNode.getChannelByName.return_value = channel
# with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
# with caplog.at_level(logging.DEBUG):
# main()
# onGPIOreceive(packet, mo)
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'Reading GPIO mask 0x1000 ', out, re.MULTILINE)
# assert re.search(r'Received RemoteHardware typ=READ_GPIOS_REPLY, gpio_value=4096', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# @patch('time.sleep')
# def test_main_gpio_rd_with_no_gpioMask(caplog, capsys):
# """Test --gpio_rd with a named gpio channel"""
# sys.argv = ['', '--gpio-rd', '0x1000', '--dest', '!1234']
# mt_config.args = sys.argv
#
# channel = Channel(index=1, role=1)
# channel.settings.modem_config = 3
# channel.settings.psk = b'\x01'
#
# # Note: Intentionally do not have gpioValue in response as that is the
# # default value
# packet = {
# 'from': 682968668,
# 'to': 682968612,
# 'channel': 1,
# 'decoded': {
# 'portnum': 'REMOTE_HARDWARE_APP',
# 'payload': b'\x08\x05\x18\x80 ',
# 'requestId': 1629980484,
# 'remotehw': {
# 'typ': 'READ_GPIOS_REPLY',
# 'raw': 'faked',
# 'id': 1693085229,
# 'rxTime': 1640294262,
# 'rxSnr': 4.75,
# 'hopLimit': 3,
# 'wantAck': True,
# }
# }
# }
#
# iface = MagicMock(autospec=SerialInterface)
# iface.localNode.getChannelByName.return_value = channel
# with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
# with caplog.at_level(logging.DEBUG):
# main()
# onGPIOreceive(packet, mo)
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'Reading GPIO mask 0x1000 ', out, re.MULTILINE)
# assert re.search(r'Received RemoteHardware typ=READ_GPIOS_REPLY, gpio_value=0', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_gpio_watch(caplog, capsys):
# """Test --gpio_watch with a named gpio channel"""
# sys.argv = ['', '--gpio-watch', '0x1000', '--dest', '!1234']
# mt_config.args = sys.argv
#
# def my_sleep(amount):
# print(f'{amount}')
# sys.exit(3)
#
# channel = Channel(index=1, role=1)
# channel.settings.modem_config = 3
# channel.settings.psk = b'\x01'
#
# packet = {
#
# 'from': 682968668,
# 'to': 682968612,
# 'channel': 1,
# 'decoded': {
# 'portnum': 'REMOTE_HARDWARE_APP',
# 'payload': b'\x08\x05\x18\x80 ',
# 'requestId': 1629980484,
# 'remotehw': {
# 'typ': 'READ_GPIOS_REPLY',
# 'gpioValue': '4096',
# 'raw': 'faked',
# 'id': 1693085229,
# 'rxTime': 1640294262,
# 'rxSnr': 4.75,
# 'hopLimit': 3,
# 'wantAck': True,
# }
# }
# }
#
# with patch('time.sleep', side_effect=my_sleep):
# with pytest.raises(SystemExit) as pytest_wrapped_e:
# iface = MagicMock(autospec=SerialInterface)
# iface.localNode.getChannelByName.return_value = channel
# with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
# with caplog.at_level(logging.DEBUG):
# main()
# onGPIOreceive(packet, mo)
# assert pytest_wrapped_e.type == SystemExit
# assert pytest_wrapped_e.value.code == 3
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'Watching GPIO mask 0x1000 ', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_gpio_wrb(caplog, capsys):
# """Test --gpio_wrb with a named gpio channel"""
# sys.argv = ['', '--gpio-wrb', '4', '1', '--dest', '!1234']
# mt_config.args = sys.argv
#
# channel = Channel(index=1, role=1)
# channel.settings.modem_config = 3
# channel.settings.psk = b'\x01'
#
# packet = {
#
# 'from': 682968668,
# 'to': 682968612,
# 'channel': 1,
# 'decoded': {
# 'portnum': 'REMOTE_HARDWARE_APP',
# 'payload': b'\x08\x05\x18\x80 ',
# 'requestId': 1629980484,
# 'remotehw': {
# 'typ': 'READ_GPIOS_REPLY',
# 'gpioValue': '16',
# 'raw': 'faked',
# 'id': 1693085229,
# 'rxTime': 1640294262,
# 'rxSnr': 4.75,
# 'hopLimit': 3,
# 'wantAck': True,
# }
# }
# }
#
#
# iface = MagicMock(autospec=SerialInterface)
# iface.localNode.getChannelByName.return_value = channel
# with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
# with caplog.at_level(logging.DEBUG):
# main()
# onGPIOreceive(packet, mo)
# out, err = capsys.readouterr()
# assert re.search(r'Connected to radio', out, re.MULTILINE)
# assert re.search(r'Writing GPIO mask 0x10 with value 0x10 to !1234', out, re.MULTILINE)
# assert re.search(r'Received RemoteHardware typ=READ_GPIOS_REPLY, gpio_value=16 value=0', out, re.MULTILINE)
# assert err == ''
# TODO
# need to restructure these for nested configs
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_getPref_valid_field(capsys):
# """Test getPref() with a valid field"""
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = "ls_secs"
# prefs.wifi_ssid = "foo"
# prefs.ls_secs = 300
# prefs.fixed_position = False
#
# getPref(prefs, "ls_secs")
# out, err = capsys.readouterr()
# assert re.search(r"ls_secs: 300", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_getPref_valid_field_camel(capsys):
# """Test getPref() with a valid field"""
# mt_config.camel_case = True
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = "ls_secs"
# prefs.wifi_ssid = "foo"
# prefs.ls_secs = 300
# prefs.fixed_position = False
#
# getPref(prefs, "ls_secs")
# out, err = capsys.readouterr()
# assert re.search(r"lsSecs: 300", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_getPref_valid_field_string(capsys):
# """Test getPref() with a valid field and value as a string"""
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = "wifi_ssid"
# prefs.wifi_ssid = "foo"
# prefs.ls_secs = 300
# prefs.fixed_position = False
#
# getPref(prefs, "wifi_ssid")
# out, err = capsys.readouterr()
# assert re.search(r"wifi_ssid: foo", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_getPref_valid_field_string_camel(capsys):
# """Test getPref() with a valid field and value as a string"""
# mt_config.camel_case = True
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = "wifi_ssid"
# prefs.wifi_ssid = "foo"
# prefs.ls_secs = 300
# prefs.fixed_position = False
#
# getPref(prefs, "wifi_ssid")
# out, err = capsys.readouterr()
# assert re.search(r"wifiSsid: foo", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_getPref_valid_field_bool(capsys):
# """Test getPref() with a valid field and value as a bool"""
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = "fixed_position"
# prefs.wifi_ssid = "foo"
# prefs.ls_secs = 300
# prefs.fixed_position = False
#
# getPref(prefs, "fixed_position")
# out, err = capsys.readouterr()
# assert re.search(r"fixed_position: False", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_getPref_valid_field_bool_camel(capsys):
# """Test getPref() with a valid field and value as a bool"""
# mt_config.camel_case = True
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = "fixed_position"
# prefs.wifi_ssid = "foo"
# prefs.ls_secs = 300
# prefs.fixed_position = False
#
# getPref(prefs, "fixed_position")
# out, err = capsys.readouterr()
# assert re.search(r"fixedPosition: False", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_getPref_invalid_field(capsys):
# """Test getPref() with an invalid field"""
#
# class Field:
# """Simple class for testing."""
#
# def __init__(self, name):
# """constructor"""
# self.name = name
#
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = None
#
# # Note: This is a subset of the real fields
# ls_secs_field = Field("ls_secs")
# is_router = Field("is_router")
# fixed_position = Field("fixed_position")
#
# fields = [ls_secs_field, is_router, fixed_position]
# prefs.DESCRIPTOR.fields = fields
#
# getPref(prefs, "foo")
#
# out, err = capsys.readouterr()
# assert re.search(r"does not have an attribute called foo", out, re.MULTILINE)
# # ensure they are sorted
# assert re.search(r"fixed_position\s+is_router\s+ls_secs", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_getPref_invalid_field_camel(capsys):
# """Test getPref() with an invalid field"""
# mt_config.camel_case = True
#
# class Field:
# """Simple class for testing."""
#
# def __init__(self, name):
# """constructor"""
# self.name = name
#
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = None
#
# # Note: This is a subset of the real fields
# ls_secs_field = Field("ls_secs")
# is_router = Field("is_router")
# fixed_position = Field("fixed_position")
#
# fields = [ls_secs_field, is_router, fixed_position]
# prefs.DESCRIPTOR.fields = fields
#
# getPref(prefs, "foo")
#
# out, err = capsys.readouterr()
# assert re.search(r"does not have an attribute called foo", out, re.MULTILINE)
# # ensure they are sorted
# assert re.search(r"fixedPosition\s+isRouter\s+lsSecs", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_setPref_valid_field_int_as_string(capsys):
# """Test setPref() with a valid field"""
#
# class Field:
# """Simple class for testing."""
#
# def __init__(self, name, enum_type):
# """constructor"""
# self.name = name
# self.enum_type = enum_type
#
# ls_secs_field = Field("ls_secs", "int")
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = ls_secs_field
#
# setPref(prefs, "ls_secs", "300")
# out, err = capsys.readouterr()
# assert re.search(r"Set ls_secs to 300", out, re.MULTILINE)
# assert err == ""
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_setPref_valid_field_invalid_enum(capsys, caplog):
# """Test setPref() with a valid field but invalid enum value"""
#
# radioConfig = RadioConfig()
# prefs = radioConfig.preferences
#
# with caplog.at_level(logging.DEBUG):
# setPref(prefs, 'charge_current', 'foo')
# out, err = capsys.readouterr()
# assert re.search(r'charge_current does not have an enum called foo', out, re.MULTILINE)
# assert re.search(r'Choices in sorted order are', out, re.MULTILINE)
# assert re.search(r'MA100', out, re.MULTILINE)
# assert re.search(r'MA280', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_setPref_valid_field_invalid_enum_where_enums_are_camel_cased_values(capsys, caplog):
# """Test setPref() with a valid field but invalid enum value"""
#
# radioConfig = RadioConfig()
# prefs = radioConfig.preferences
#
# with caplog.at_level(logging.DEBUG):
# setPref(prefs, 'region', 'foo')
# out, err = capsys.readouterr()
# assert re.search(r'region does not have an enum called foo', out, re.MULTILINE)
# assert re.search(r'Choices in sorted order are', out, re.MULTILINE)
# assert re.search(r'ANZ', out, re.MULTILINE)
# assert re.search(r'CN', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_setPref_valid_field_invalid_enum_camel(capsys, caplog):
# """Test setPref() with a valid field but invalid enum value"""
# mt_config.camel_case = True
#
# radioConfig = RadioConfig()
# prefs = radioConfig.preferences
#
# with caplog.at_level(logging.DEBUG):
# setPref(prefs, 'charge_current', 'foo')
# out, err = capsys.readouterr()
# assert re.search(r'chargeCurrent does not have an enum called foo', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_setPref_valid_field_valid_enum(capsys, caplog):
# """Test setPref() with a valid field and valid enum value"""
#
# # charge_current
# # some valid values: MA100 MA1000 MA1080
#
# radioConfig = RadioConfig()
# prefs = radioConfig.preferences
#
# with caplog.at_level(logging.DEBUG):
# setPref(prefs, 'charge_current', 'MA100')
# out, err = capsys.readouterr()
# assert re.search(r'Set charge_current to MA100', out, re.MULTILINE)
# assert err == ''
# TODO
# @pytest.mark.unit
# @pytest.mark.usefixtures("reset_mt_config")
# def test_main_setPref_valid_field_valid_enum_camel(capsys, caplog):
# """Test setPref() with a valid field and valid enum value"""
# mt_config.camel_case = True
#
# # charge_current
# # some valid values: MA100 MA1000 MA1080
#
# radioConfig = RadioConfig()
# prefs = radioConfig.preferences
#
# with caplog.at_level(logging.DEBUG):
# setPref(prefs, 'charge_current', 'MA100')
# out, err = capsys.readouterr()
# assert re.search(r'Set chargeCurrent to MA100', out, re.MULTILINE)
# assert err == ''
# TODO
# need to update for nested configs
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_setPref_invalid_field(capsys):
# """Test setPref() with a invalid field"""
#
# class Field:
# """Simple class for testing."""
#
# def __init__(self, name):
# """constructor"""
# self.name = name
#
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = None
#
# # Note: This is a subset of the real fields
# ls_secs_field = Field("ls_secs")
# is_router = Field("is_router")
# fixed_position = Field("fixed_position")
#
# fields = [ls_secs_field, is_router, fixed_position]
# prefs.DESCRIPTOR.fields = fields
#
# setPref(prefs, "foo", "300")
# out, err = capsys.readouterr()
# assert re.search(r"does not have an attribute called foo", out, re.MULTILINE)
# # ensure they are sorted
# assert re.search(r"fixed_position\s+is_router\s+ls_secs", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_setPref_invalid_field_camel(capsys):
# """Test setPref() with a invalid field"""
# mt_config.camel_case = True
#
# class Field:
# """Simple class for testing."""
#
# def __init__(self, name):
# """constructor"""
# self.name = name
#
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = None
#
# # Note: This is a subset of the real fields
# ls_secs_field = Field("ls_secs")
# is_router = Field("is_router")
# fixed_position = Field("fixed_position")
#
# fields = [ls_secs_field, is_router, fixed_position]
# prefs.DESCRIPTOR.fields = fields
#
# setPref(prefs, "foo", "300")
# out, err = capsys.readouterr()
# assert re.search(r"does not have an attribute called foo", out, re.MULTILINE)
# # ensure they are sorted
# assert re.search(r"fixedPosition\s+isRouter\s+lsSecs", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_setPref_ignore_incoming_123(capsys):
# """Test setPref() with ignore_incoming"""
#
# class Field:
# """Simple class for testing."""
#
# def __init__(self, name, enum_type):
# """constructor"""
# self.name = name
# self.enum_type = enum_type
#
# ignore_incoming_field = Field("ignore_incoming", "list")
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = ignore_incoming_field
#
# setPref(prefs, "ignore_incoming", "123")
# out, err = capsys.readouterr()
# assert re.search(r"Adding '123' to the ignore_incoming list", out, re.MULTILINE)
# assert re.search(r"Set ignore_incoming to 123", out, re.MULTILINE)
# assert err == ""
#
#
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_setPref_ignore_incoming_0(capsys):
# """Test setPref() with ignore_incoming"""
#
# class Field:
# """Simple class for testing."""
#
# def __init__(self, name, enum_type):
# """constructor"""
# self.name = name
# self.enum_type = enum_type
#
# ignore_incoming_field = Field("ignore_incoming", "list")
# prefs = MagicMock()
# prefs.DESCRIPTOR.fields_by_name.get.return_value = ignore_incoming_field
#
# setPref(prefs, "ignore_incoming", "0")
# out, err = capsys.readouterr()
# assert re.search(r"Clearing ignore_incoming list", out, re.MULTILINE)
# assert re.search(r"Set ignore_incoming to 0", out, re.MULTILINE)
# assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_set_psk_no_ch_index(capsys):
"""Test --ch-set psk"""
sys.argv = ["", "--ch-set", "psk", "foo", "--host", "meshtastic.local"]
mt_config.args = sys.argv
iface = MagicMock(autospec=TCPInterface)
with patch("meshtastic.tcp_interface.TCPInterface", return_value=iface) as mo:
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Warning: Need to specify '--ch-index'", out, re.MULTILINE)
assert err == ""
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_ch_set_psk_with_ch_index(capsys):
"""Test --ch-set psk"""
sys.argv = [
"",
"--ch-set",
"psk",
"foo",
"--host",
"meshtastic.local",
"--ch-index",
"0",
]
mt_config.args = sys.argv
iface = MagicMock(autospec=TCPInterface)
with patch("meshtastic.tcp_interface.TCPInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Writing modified channels to device", out, re.MULTILINE)
assert err == ""
mo.assert_called()
# TODO
# doesn't work properly with nested/module config stuff
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_mt_config")
#def test_main_ch_set_name_with_ch_index(capsys):
# """Test --ch-set setting other than psk"""
# sys.argv = [
# "",
# "--ch-set",
# "name",
# "foo",
# "--host",
# "meshtastic.local",
# "--ch-index",
# "0",
# ]
# mt_config.args = sys.argv
#
# iface = MagicMock(autospec=TCPInterface)
# with patch("meshtastic.tcp_interface.TCPInterface", return_value=iface) as mo:
# main()
# out, err = capsys.readouterr()
# assert re.search(r"Connected to radio", out, re.MULTILINE)
# assert re.search(r"Set name to foo", out, re.MULTILINE)
# assert re.search(r"Writing modified channels to device", out, re.MULTILINE)
# assert err == ""
# mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_onNode(capsys):
"""Test onNode"""
onNode("foo")
out, err = capsys.readouterr()
assert re.search(r"Node changed", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_tunnel_no_args(capsys):
"""Test tunnel no arguments"""
sys.argv = [""]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as pytest_wrapped_e:
tunnelMain()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
_, err = capsys.readouterr()
assert re.search(r"usage: ", err, re.MULTILINE)
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.util.findPorts", return_value=[])
@patch("platform.system")
def test_tunnel_tunnel_arg_with_no_devices(mock_platform_system, caplog, capsys):
"""Test tunnel with tunnel arg (act like we are on a linux system)"""
a_mock = MagicMock()
a_mock.return_value = "Linux"
mock_platform_system.side_effect = a_mock
sys.argv = ["", "--tunnel"]
mt_config.args = sys.argv
print(f"platform.system():{platform.system()}")
with caplog.at_level(logging.DEBUG):
with pytest.raises(SystemExit) as pytest_wrapped_e:
tunnelMain()
mock_platform_system.assert_called()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"No.*Meshtastic.*device.*detected", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.util.findPorts", return_value=[])
@patch("platform.system")
def test_tunnel_subnet_arg_with_no_devices(mock_platform_system, caplog, capsys):
"""Test tunnel with subnet arg (act like we are on a linux system)"""
a_mock = MagicMock()
a_mock.return_value = "Linux"
mock_platform_system.side_effect = a_mock
sys.argv = ["", "--subnet", "foo"]
mt_config.args = sys.argv
print(f"platform.system():{platform.system()}")
with caplog.at_level(logging.DEBUG):
with pytest.raises(SystemExit) as pytest_wrapped_e:
tunnelMain()
mock_platform_system.assert_called()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.search(r"No.*Meshtastic.*device.*detected", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("platform.system")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_tunnel_tunnel_arg(
mocked_findPorts, mocked_serial, mocked_open, mock_get, mock_set, mock_platform_system, caplog, iface_with_nodes, capsys
):
"""Test tunnel with tunnel arg (act like we are on a linux system)"""
# Override the time.sleep so there is no loop
def my_sleep(amount):
print(f"{amount}")
sys.exit(3)
a_mock = MagicMock()
a_mock.return_value = "Linux"
mock_platform_system.side_effect = a_mock
sys.argv = ["", "--tunnel"]
mt_config.args = sys.argv
serialInterface = SerialInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface):
with patch("time.sleep", side_effect=my_sleep):
with pytest.raises(SystemExit) as pytest_wrapped_e:
tunnelMain()
mock_platform_system.assert_called()
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 3
assert re.search(r"Not starting Tunnel", caplog.text, re.MULTILINE)
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert err == ""
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_set_favorite_node():
"""Test --set-favorite-node node"""
sys.argv = ["", "--set-favorite-node", "!12345678"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
main()
mocked_node.setFavorite.assert_called_once_with("!12345678")
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_remove_favorite_node():
"""Test --remove-favorite-node node"""
sys.argv = ["", "--remove-favorite-node", "!12345678"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
mocked_node.iface = iface
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
main()
mocked_node.removeFavorite.assert_called_once_with("!12345678")
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_set_ignored_node():
"""Test --set-ignored-node node"""
sys.argv = ["", "--set-ignored-node", "!12345678"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
main()
mocked_node.setIgnored.assert_called_once_with("!12345678")
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_remove_ignored_node():
"""Test --remove-ignored-node node"""
sys.argv = ["", "--remove-ignored-node", "!12345678"]
mt_config.args = sys.argv
mocked_node = MagicMock(autospec=Node)
iface = MagicMock(autospec=SerialInterface)
iface.getNode.return_value = mocked_node
mocked_node.iface = iface
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
main()
mocked_node.removeIgnored.assert_called_once_with("!12345678")
Functions
def test_main_ch_add_but_name_already_exists(capsys)
-
Test –ch-add with a channel name that already exists
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_add_but_name_already_exists(capsys): """Test --ch-add with a channel name that already exists""" sys.argv = ["", "--ch-add", "testing"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) # set it up so we do not already have a channel named this mocked_node.getChannelByName.return_value = True iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: This node already has", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_ch_add_but_no_more_channels(capsys)
-
Test –ch-add with but there are no more channels
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_add_but_no_more_channels(capsys): """Test --ch-add with but there are no more channels""" sys.argv = ["", "--ch-add", "testing"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) # set it up so we do not already have a channel named this mocked_node.getChannelByName.return_value = False # set it up so we have free channels mocked_node.getDisabledChannel.return_value = None iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: No free channels were found", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_ch_add_invalid_name_too_long(capsys)
-
Test –ch-add with invalid channel name, name too long
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_add_invalid_name_too_long(capsys): """Test --ch-add with invalid channel name, name too long""" sys.argv = ["", "--ch-add", "testingtestingtesting"] mt_config.args = sys.argv mocked_channel = MagicMock(autospec=Channel) # TODO: figure out how to get it to print the channel name instead of MagicMock mocked_node = MagicMock(autospec=Node) # set it up so we do not already have a channel named this mocked_node.getChannelByName.return_value = False # set it up so we have free channels mocked_node.getDisabledChannel.return_value = mocked_channel iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: Channel name must be shorter", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_ch_add_valid(capsys)
-
Test –ch-add with valid channel name, and that channel name does not already exist
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_add_valid(capsys): """Test --ch-add with valid channel name, and that channel name does not already exist""" sys.argv = ["", "--ch-add", "testing"] mt_config.args = sys.argv mocked_channel = MagicMock(autospec=Channel) # TODO: figure out how to get it to print the channel name instead of MagicMock mocked_node = MagicMock(autospec=Node) # set it up so we do not already have a channel named this mocked_node.getChannelByName.return_value = False # set it up so we have free channels mocked_node.getDisabledChannel.return_value = mocked_channel iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Writing modified channels to device", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_ch_del(capsys)
-
Test –ch-del with valid secondary channel to be deleted
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_del(capsys): """Test --ch-del with valid secondary channel to be deleted""" sys.argv = ["", "--ch-del", "--ch-index", "1"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Deleting channel", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_ch_del_no_ch_index_specified(capsys)
-
Test –ch-del without a valid ch-index
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_del_no_ch_index_specified(capsys): """Test --ch-del without a valid ch-index""" sys.argv = ["", "--ch-del"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: Need to specify", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_ch_del_primary_channel(capsys)
-
Test –ch-del on ch-index=0
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_del_primary_channel(capsys): """Test --ch-del on ch-index=0""" sys.argv = ["", "--ch-del", "--ch-index", "0"] mt_config.args = sys.argv mt_config.channel_index = 1 mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: Cannot delete primary channel", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_ch_disable_valid_secondary_channel(capsys)
-
Test –ch-disable with –ch-index
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_disable_valid_secondary_channel(capsys): """Test --ch-disable with --ch-index""" sys.argv = ["", "--ch-disable", "--ch-index", "1"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Writing modified channels", out, re.MULTILINE) assert err == "" assert mt_config.channel_index == 1 mo.assert_called()
def test_main_ch_enable_primary_channel(capsys)
-
Test –ch-enable with –ch-index = 0
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_enable_primary_channel(capsys): """Test --ch-enable with --ch-index = 0""" sys.argv = ["", "--ch-enable", "--ch-index", "0"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: Cannot enable/disable PRIMARY", out, re.MULTILINE) assert err == "" assert mt_config.channel_index == 0 mo.assert_called()
def test_main_ch_enable_valid_secondary_channel(capsys)
-
Test –ch-enable with –ch-index
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_enable_valid_secondary_channel(capsys): """Test --ch-enable with --ch-index""" sys.argv = ["", "--ch-enable", "--ch-index", "1"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Writing modified channels", out, re.MULTILINE) assert err == "" assert mt_config.channel_index == 1 mo.assert_called()
def test_main_ch_enable_without_a_ch_index(capsys)
-
Test –ch-enable without –ch-index
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_enable_without_a_ch_index(capsys): """Test --ch-enable without --ch-index""" sys.argv = ["", "--ch-enable"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: Need to specify", out, re.MULTILINE) assert err == "" assert mt_config.channel_index is None mo.assert_called()
def test_main_ch_index_no_devices(patched_find_ports, capsys)
-
Test –ch-index 1
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("meshtastic.util.findPorts", return_value=[]) def test_main_ch_index_no_devices(patched_find_ports, capsys): """Test --ch-index 1""" sys.argv = ["", "--ch-index", "1"] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert mt_config.channel_index == 1 assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"No.*Meshtastic.*device.*detected", out, re.MULTILINE) assert err == "" patched_find_ports.assert_called()
def test_main_ch_longfast_on_non_primary_channel(capsys)
-
Test –ch-longfast –ch-index 1
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_longfast_on_non_primary_channel(capsys): """Test --ch-longfast --ch-index 1""" sys.argv = ["", "--ch-longfast", "--ch-index", "1"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: Cannot set modem preset for non-primary channel", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_ch_set_psk_no_ch_index(capsys)
-
Test –ch-set psk
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_set_psk_no_ch_index(capsys): """Test --ch-set psk""" sys.argv = ["", "--ch-set", "psk", "foo", "--host", "meshtastic.local"] mt_config.args = sys.argv iface = MagicMock(autospec=TCPInterface) with patch("meshtastic.tcp_interface.TCPInterface", return_value=iface) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Warning: Need to specify '--ch-index'", out, re.MULTILINE) assert err == "" assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 mo.assert_called()
def test_main_ch_set_psk_with_ch_index(capsys)
-
Test –ch-set psk
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_ch_set_psk_with_ch_index(capsys): """Test --ch-set psk""" sys.argv = [ "", "--ch-set", "psk", "foo", "--host", "meshtastic.local", "--ch-index", "0", ] mt_config.args = sys.argv iface = MagicMock(autospec=TCPInterface) with patch("meshtastic.tcp_interface.TCPInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Writing modified channels to device", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_configure_with_camel_case_keys(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys)
-
Test –configure with valid file
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_main_configure_with_camel_case_keys(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys): """Test --configure with valid file""" sys.argv = ["", "--configure", "exampleConfig.yaml"] mt_config.args = sys.argv serialInterface = SerialInterface(noProto=True) anode = Node(serialInterface, 1234567890, noProto=True) serialInterface.localNode = anode with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) # should these come back? maybe a flag? #assert re.search(r"Setting device owner", out, re.MULTILINE) #assert re.search(r"Setting device owner short", out, re.MULTILINE) #assert re.search(r"Setting channel url", out, re.MULTILINE) #assert re.search(r"Fixing altitude", out, re.MULTILINE) #assert re.search(r"Fixing latitude", out, re.MULTILINE) #assert re.search(r"Fixing longitude", out, re.MULTILINE) assert re.search(r"Writing modified configuration to device", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_configure_with_snake_case(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys)
-
Test –configure with valid file
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_main_configure_with_snake_case(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys): """Test --configure with valid file""" sys.argv = ["", "--configure", "example_config.yaml"] mt_config.args = sys.argv serialInterface = SerialInterface(noProto=True) anode = Node(serialInterface, 1234567890, noProto=True) serialInterface.localNode = anode with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) # should these come back? maybe a flag? #assert re.search(r"Setting device owner", out, re.MULTILINE) #assert re.search(r"Setting device owner short", out, re.MULTILINE) #assert re.search(r"Setting channel url", out, re.MULTILINE) #assert re.search(r"Fixing altitude", out, re.MULTILINE) #assert re.search(r"Fixing latitude", out, re.MULTILINE) #assert re.search(r"Fixing longitude", out, re.MULTILINE) #assert re.search(r"Set location_share to LocEnabled", out, re.MULTILINE) assert re.search(r"Writing modified configuration to device", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_export_config(capsys)
-
Test export_config() function directly
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_export_config(capsys): """Test export_config() function directly""" iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: mo.getLongName.return_value = "foo" mo.getShortName.return_value = "oof" mo.localNode.getURL.return_value = "bar" mo.getMyNodeInfo().get.return_value = { "latitudeI": 1100000000, "longitudeI": 1200000000, "altitude": 100, "batteryLevel": 34, "latitude": 110.0, "longitude": 120.0, } mo.localNode.radioConfig.preferences = """phone_timeout_secs: 900 ls_secs: 300 position_broadcast_smart: true fixed_position: true position_flags: 35""" export_config(mo) out, err = capsys.readouterr() # ensure we do not output this line assert not re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"owner: foo", out, re.MULTILINE) assert re.search(r"owner_short: oof", out, re.MULTILINE) assert re.search(r"channel_url: bar", out, re.MULTILINE) assert re.search(r"location:", out, re.MULTILINE) assert re.search(r"lat: 110.0", out, re.MULTILINE) assert re.search(r"lon: 120.0", out, re.MULTILINE) assert re.search(r"alt: 100", out, re.MULTILINE) # TODO: rework above config to test the following #assert re.search(r"user_prefs:", out, re.MULTILINE) #assert re.search(r"phone_timeout_secs: 900", out, re.MULTILINE) #assert re.search(r"ls_secs: 300", out, re.MULTILINE) #assert re.search(r"position_broadcast_smart: 'true'", out, re.MULTILINE) #assert re.search(r"fixed_position: 'true'", out, re.MULTILINE) #assert re.search(r"position_flags: 35", out, re.MULTILINE) assert err == ""
def test_main_get_canned_messages(capsys, caplog, iface_with_nodes)
-
Test –get-canned-message
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_get_canned_messages(capsys, caplog, iface_with_nodes): """Test --get-canned-message""" sys.argv = ["", "--get-canned-message"] mt_config.args = sys.argv iface = iface_with_nodes iface.localNode.cannedPluginMessage = "foo" iface.devPath = "bar" with caplog.at_level(logging.DEBUG): with patch( "meshtastic.serial_interface.SerialInterface", return_value=iface ) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"canned_plugin_message:foo", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_get_with_invalid(capsys)
-
Test –get with invalid field
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_get_with_invalid(capsys): """Test --get with invalid field""" sys.argv = ["", "--get", "foo"] mt_config.args = sys.argv mocked_user_prefs = MagicMock() mocked_user_prefs.DESCRIPTOR.fields_by_name.get.return_value = None mocked_node = MagicMock(autospec=Node) mocked_node.localConfig = mocked_user_prefs mocked_node.moduleConfig = mocked_user_prefs iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"do not have attribute foo", out, re.MULTILINE) assert re.search(r"Choices are...", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_gpio_rd_no_dest(capsys)
-
Test –gpio_rd with a named gpio channel but no dest was specified
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_gpio_rd_no_dest(capsys): """Test --gpio_rd with a named gpio channel but no dest was specified""" sys.argv = ["", "--gpio-rd", "0x2000"] mt_config.args = sys.argv channel = Channel(index=2, role=2) channel.settings.psk = b"\x8a\x94y\x0e\xc6\xc9\x1e5\x91\x12@\xa60\xa8\xb43\x87\x00\xf2K\x0e\xe7\x7fAz\xcd\xf5\xb0\x900\xa84" channel.settings.name = "gpio" iface = MagicMock(autospec=SerialInterface) iface.localNode.getChannelByName.return_value = channel with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Warning: Must use a destination node ID", out) assert err == ""
def test_main_gpio_rd_no_gpio_channel(capsys)
-
Test –gpio_rd with no named gpio channel
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_gpio_rd_no_gpio_channel(capsys): """Test --gpio_rd with no named gpio channel""" sys.argv = ["", "--gpio-rd", "0x10", "--dest", "!foo"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) iface.localNode.getChannelByName.return_value = None with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Warning: No channel named", out) assert err == ""
def test_main_info(capsys, caplog)
-
Test –info
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_info(capsys, caplog): """Test --info""" sys.argv = ["", "--info"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) def mock_showInfo(): print("inside mocked showInfo") iface.showInfo.side_effect = mock_showInfo with caplog.at_level(logging.DEBUG): with patch( "meshtastic.serial_interface.SerialInterface", return_value=iface ) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"inside mocked showInfo", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_info_with_permission_error(patched_getlogin, capsys, caplog)
-
Test –info
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("os.getlogin") def test_main_info_with_permission_error(patched_getlogin, capsys, caplog): """Test --info""" sys.argv = ["", "--info"] mt_config.args = sys.argv patched_getlogin.return_value = "me" iface = MagicMock(autospec=SerialInterface) with caplog.at_level(logging.DEBUG): with pytest.raises(SystemExit) as pytest_wrapped_e: with patch( "meshtastic.serial_interface.SerialInterface", return_value=iface ) as mo: mo.side_effect = PermissionError("bla bla") main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() patched_getlogin.assert_called() assert re.search(r"Need to add yourself", out, re.MULTILINE) assert err == ""
def test_main_info_with_seriallog_output_txt(capsys)
-
Test –info
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_info_with_seriallog_output_txt(capsys): """Test --info""" sys.argv = ["", "--info", "--seriallog", "output.txt"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) def mock_showInfo(): print("inside mocked showInfo") iface.showInfo.side_effect = mock_showInfo with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"inside mocked showInfo", out, re.MULTILINE) assert err == "" mo.assert_called() # do some cleanup os.remove("output.txt")
def test_main_info_with_seriallog_stdout(capsys)
-
Test –info
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_info_with_seriallog_stdout(capsys): """Test --info""" sys.argv = ["", "--info", "--seriallog", "stdout"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) def mock_showInfo(): print("inside mocked showInfo") iface.showInfo.side_effect = mock_showInfo with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"inside mocked showInfo", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_info_with_tcp_interface(capsys)
-
Test –info
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_info_with_tcp_interface(capsys): """Test --info""" sys.argv = ["", "--info", "--host", "meshtastic.local"] mt_config.args = sys.argv iface = MagicMock(autospec=TCPInterface) def mock_showInfo(): print("inside mocked showInfo") iface.showInfo.side_effect = mock_showInfo with patch("meshtastic.tcp_interface.TCPInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"inside mocked showInfo", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_init_parser_no_args(capsys)
-
Test no arguments
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_init_parser_no_args(capsys): """Test no arguments""" sys.argv = [""] mt_config.args = sys.argv initParser() out, err = capsys.readouterr() assert out == "" assert err == ""
def test_main_init_parser_version(capsys)
-
Test –version
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_init_parser_version(capsys): """Test --version""" sys.argv = ["", "--version"] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: initParser() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 0 out, err = capsys.readouterr() assert re.match(r"[0-9]+\.[0-9]+[\.a][0-9]", out) assert err == ""
def test_main_main_no_args(capsys)
-
Test with no args
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_main_no_args(capsys): """Test with no args""" sys.argv = [""] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 _, err = capsys.readouterr() assert re.search(r"usage:", err, re.MULTILINE)
def test_main_main_version(capsys)
-
Test –version
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_main_version(capsys): """Test --version""" sys.argv = ["", "--version"] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 0 out, err = capsys.readouterr() assert re.match(r"[0-9]+\.[0-9]+[\.a][0-9]", out) assert err == ""
def test_main_no_proto(capsys)
-
Test –noproto (using –info for output)
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_no_proto(capsys): """Test --noproto (using --info for output)""" sys.argv = ["", "--info", "--noproto"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) def mock_showInfo(): print("inside mocked showInfo") iface.showInfo.side_effect = mock_showInfo # Override the time.sleep so there is no loop def my_sleep(amount): print(f"amount:{amount}") sys.exit(0) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): with patch("time.sleep", side_effect=my_sleep): with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 0 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"inside mocked showInfo", out, re.MULTILINE) assert err == ""
def test_main_nodes(capsys)
-
Test –nodes
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_nodes(capsys): """Test --nodes""" sys.argv = ["", "--nodes"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) def mock_showNodes(includeSelf, showFields): print(f"inside mocked showNodes: {includeSelf} {showFields}") iface.showNodes.side_effect = mock_showNodes with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"inside mocked showNodes", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_onConnected_exception(capsys)
-
Test the exception in onConnected
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_onConnected_exception(capsys): """Test the exception in onConnected""" sys.argv = ["", "--qr"] mt_config.args = sys.argv def throw_an_exception(junk): raise Exception("Fake exception.") # pylint: disable=W0719 iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): with patch("pyqrcode.create", side_effect=throw_an_exception): with pytest.raises(SystemExit) as pytest_wrapped_e: main() out, err = capsys.readouterr() assert re.search("Aborting due to: Fake exception", out, re.MULTILINE) assert err == "" assert pytest_wrapped_e.type == Exception
def test_main_onConnection(capsys)
-
Test onConnection
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_onConnection(capsys): """Test onConnection""" sys.argv = [""] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) class TempTopic: """temp class for topic""" def getName(self): """return the fake name of a topic""" return "foo" mytopic = TempTopic() onConnection(iface, mytopic) out, err = capsys.readouterr() assert re.search(r"Connection changed: foo", out, re.MULTILINE) assert err == ""
def test_main_onReceive_empty(caplog, capsys)
-
Test onReceive
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_onReceive_empty(caplog, capsys): """Test onReceive""" args = MagicMock() mt_config.args = args iface = MagicMock(autospec=SerialInterface) packet = {} with caplog.at_level(logging.DEBUG): onReceive(packet, iface) assert re.search(r"in onReceive", caplog.text, re.MULTILINE) out, err = capsys.readouterr() assert re.search( r"Warning: Error processing received packet: 'to'.", out, re.MULTILINE ) assert err == ""
def test_main_onReceive_with_sendtext(caplog, capsys)
-
Test onReceive with sendtext The entire point of this test is to make sure the interface.close() call is made in onReceive().
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_onReceive_with_sendtext(caplog, capsys): """Test onReceive with sendtext The entire point of this test is to make sure the interface.close() call is made in onReceive(). """ sys.argv = ["", "--sendtext", "hello"] mt_config.args = sys.argv # Note: 'TEXT_MESSAGE_APP' value is 1 packet = { "to": 4294967295, "decoded": {"portnum": 1, "payload": "hello"}, "id": 334776977, "hop_limit": 3, "want_ack": True, } iface = MagicMock(autospec=SerialInterface) iface.myInfo.my_node_num = 4294967295 with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: with caplog.at_level(logging.DEBUG): main() onReceive(packet, iface) assert re.search(r"in onReceive", caplog.text, re.MULTILINE) mo.assert_called() out, err = capsys.readouterr() assert re.search(r"Sending text message hello to", out, re.MULTILINE) assert err == ""
def test_main_onReceive_with_text(caplog, capsys)
-
Test onReceive with text
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_onReceive_with_text(caplog, capsys): """Test onReceive with text""" args = MagicMock() args.sendtext.return_value = "foo" mt_config.args = args # Note: 'TEXT_MESSAGE_APP' value is 1 # Note: Some of this is faked below. packet = { "to": 4294967295, "decoded": {"portnum": 1, "payload": "hello", "text": "faked"}, "id": 334776977, "hop_limit": 3, "want_ack": True, "rxSnr": 6.0, "hopLimit": 3, "raw": "faked", "fromId": "!28b5465c", "toId": "^all", } iface = MagicMock(autospec=SerialInterface) iface.myInfo.my_node_num = 4294967295 with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): with caplog.at_level(logging.DEBUG): onReceive(packet, iface) assert re.search(r"in onReceive", caplog.text, re.MULTILINE) out, err = capsys.readouterr() assert re.search(r"Sending reply", out, re.MULTILINE) assert err == ""
def test_main_qr(capsys)
-
Test –qr
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_qr(capsys): """Test --qr""" sys.argv = ["", "--qr"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) # TODO: could mock/check url with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Primary channel URL", out, re.MULTILINE) # if a qr code is generated it will have lots of these assert re.search(r"\[7m", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_reboot(capsys)
-
Test –reboot
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_reboot(capsys): """Test --reboot""" sys.argv = ["", "--reboot"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) def mock_reboot(): print("inside mocked reboot") mocked_node.reboot.side_effect = mock_reboot iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"inside mocked reboot", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_removeposition(capsys)
-
Test –remove-position
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_removeposition(capsys): """Test --remove-position""" sys.argv = ["", "--remove-position"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) def mock_removeFixedPosition(): print("inside mocked removeFixedPosition") mocked_node.removeFixedPosition.side_effect = mock_removeFixedPosition iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Removing fixed position", out, re.MULTILINE) assert re.search(r"inside mocked removeFixedPosition", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_removeposition_remote(capsys)
-
Test –remove-position with a remote dest
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_removeposition_remote(capsys): """Test --remove-position with a remote dest""" sys.argv = ["", "--remove-position", "--dest", "!12345678"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Removing fixed position and disabling fixed position setting", out, re.MULTILINE) assert re.search(r"Waiting for an acknowledgment from remote node", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_sendtext(capsys)
-
Test –sendtext
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_sendtext(capsys): """Test --sendtext""" sys.argv = ["", "--sendtext", "hello"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) def mock_sendText( text, dest, wantAck=False, wantResponse=False, onResponse=None, channelIndex=0, portNum=0 ): print("inside mocked sendText") print(f"{text} {dest} {wantAck} {wantResponse} {channelIndex} {portNum}") iface.sendText.side_effect = mock_sendText with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Sending text message", out, re.MULTILINE) assert re.search(r"inside mocked sendText", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_sendtext_with_channel(capsys)
-
Test –sendtext
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_sendtext_with_channel(capsys): """Test --sendtext""" sys.argv = ["", "--sendtext", "hello", "--ch-index", "1"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) def mock_sendText( text, dest, wantAck=False, wantResponse=False, onResponse=None, channelIndex=0, portNum=0 ): print("inside mocked sendText") print(f"{text} {dest} {wantAck} {wantResponse} {channelIndex} {portNum}") iface.sendText.side_effect = mock_sendText with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Sending text message", out, re.MULTILINE) assert re.search(r"on channelIndex:1", out, re.MULTILINE) assert re.search(r"inside mocked sendText", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_sendtext_with_dest(mock_findPorts, mock_serial, mocked_open, mock_get, mock_set, capsys, caplog, iface_with_nodes)
-
Test –sendtext with –dest
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_main_sendtext_with_dest(mock_findPorts, mock_serial, mocked_open, mock_get, mock_set, capsys, caplog, iface_with_nodes): """Test --sendtext with --dest""" sys.argv = ["", "--sendtext", "hello", "--dest", "foo"] mt_config.args = sys.argv #iface = iface_with_nodes #iface.myInfo.my_node_num = 2475227164 serialInterface = SerialInterface(noProto=True) mocked_channel = MagicMock(autospec=Channel) serialInterface.localNode.getChannelByChannelIndex = mocked_channel with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface): with caplog.at_level(logging.DEBUG): #with pytest.raises(SystemExit) as pytest_wrapped_e: main() #assert pytest_wrapped_e.type == SystemExit #assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert not re.search( r"Warning: 0 is not a valid channel", out, re.MULTILINE ) assert not re.search( r"There is a SECONDARY channel named 'admin'", out, re.MULTILINE ) print(out) assert re.search(r"Not sending packet because", caplog.text, re.MULTILINE) assert re.search(r"Warning: There were no self.nodes.", caplog.text, re.MULTILINE) assert err == ""
def test_main_sendtext_with_invalid_channel(caplog, capsys)
-
Test –sendtext
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_sendtext_with_invalid_channel(caplog, capsys): """Test --sendtext""" sys.argv = ["", "--sendtext", "hello", "--ch-index", "-1"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) iface.localNode.getChannelByChannelIndex.return_value = None with caplog.at_level(logging.DEBUG): with patch( "meshtastic.serial_interface.SerialInterface", return_value=iface ) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"is not a valid channel", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_sendtext_with_invalid_channel_nine(caplog, capsys)
-
Test –sendtext
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_sendtext_with_invalid_channel_nine(caplog, capsys): """Test --sendtext""" sys.argv = ["", "--sendtext", "hello", "--ch-index", "9"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) iface.localNode.getChannelByChannelIndex.return_value = None with caplog.at_level(logging.DEBUG): with patch( "meshtastic.serial_interface.SerialInterface", return_value=iface ) as mo: with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"is not a valid channel", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_set_canned_messages(capsys)
-
Test –set-canned-message
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_set_canned_messages(capsys): """Test --set-canned-message""" sys.argv = ["", "--set-canned-message", "foo"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Setting canned plugin message to foo", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_set_ham_to_KI123(capsys)
-
Test –set-ham KI123
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_set_ham_to_KI123(capsys): """Test --set-ham KI123""" sys.argv = ["", "--set-ham", "KI123"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) def mock_turnOffEncryptionOnPrimaryChannel(): print("inside mocked turnOffEncryptionOnPrimaryChannel") def mock_setOwner(name, is_licensed): print(f"inside mocked setOwner name:{name} is_licensed:{is_licensed}") mocked_node.turnOffEncryptionOnPrimaryChannel.side_effect = ( mock_turnOffEncryptionOnPrimaryChannel ) mocked_node.setOwner.side_effect = mock_setOwner iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Setting Ham ID to KI123", out, re.MULTILINE) assert re.search(r"inside mocked setOwner", out, re.MULTILINE) assert re.search( r"inside mocked turnOffEncryptionOnPrimaryChannel", out, re.MULTILINE ) assert err == "" mo.assert_called()
def test_main_set_invalid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys)
-
Test –set with an invalid value (psk must be 8 or more characters)
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_main_set_invalid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys): """Test --set with an invalid value (psk must be 8 or more characters)""" sys.argv = ["", "--set", "network.wifi_psk", "1234567"] mt_config.args = sys.argv serialInterface = SerialInterface(noProto=True) anode = Node(serialInterface, 1234567890, noProto=True) serialInterface.localNode = anode with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert not re.search(r"Set network.wifi_psk to 1234567", out, re.MULTILINE) assert re.search( r"Warning: network.wifi_psk must be 8 or more characters.", out, re.MULTILINE ) assert err == "" mo.assert_called()
def test_main_set_owner_short_to_bob(capsys)
-
Test –set-owner-short bob
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_set_owner_short_to_bob(capsys): """Test --set-owner-short bob""" sys.argv = ["", "--set-owner-short", "bob"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Setting device owner short to bob", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_set_owner_to_bob(capsys)
-
Test –set-owner bob
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_set_owner_to_bob(capsys): """Test --set-owner bob""" sys.argv = ["", "--set-owner", "bob"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Setting device owner to bob", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_set_valid(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys)
-
Test –set with valid field
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_main_set_valid(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys): """Test --set with valid field""" sys.argv = ["", "--set", "network.wifi_ssid", "foo"] mt_config.args = sys.argv serialInterface = SerialInterface(noProto=True) anode = Node(serialInterface, 1234567890, noProto=True) serialInterface.localNode = anode with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Set network.wifi_ssid to foo", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_set_valid_camel_case(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys)
-
Test –set with valid field
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_main_set_valid_camel_case(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys): """Test --set with valid field""" sys.argv = ["", "--set", "network.wifi_ssid", "foo"] mt_config.args = sys.argv mt_config.camel_case = True serialInterface = SerialInterface(noProto=True) anode = Node(serialInterface, 1234567890, noProto=True) serialInterface.localNode = anode with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Set network.wifiSsid to foo", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_set_valid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys)
-
Test –set with valid field
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_main_set_valid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys): """Test --set with valid field""" sys.argv = ["", "--set", "network.wifi_psk", "123456789"] mt_config.args = sys.argv serialInterface = SerialInterface(noProto=True) anode = Node(serialInterface, 1234567890, noProto=True) serialInterface.localNode = anode with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Set network.wifi_psk to 123456789", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_set_with_invalid(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys)
-
Test –set with invalid field
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_main_set_with_invalid(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys): """Test --set with invalid field""" sys.argv = ["", "--set", "foo", "foo"] mt_config.args = sys.argv serialInterface = SerialInterface(noProto=True) anode = Node(serialInterface, 1234567890, noProto=True) serialInterface.localNode = anode with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"do not have attribute foo", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_setalt(capsys)
-
Test –setalt
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_setalt(capsys): """Test --setalt""" sys.argv = ["", "--setalt", "51"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) def mock_setFixedPosition(lat, lon, alt): print("inside mocked setFixedPosition") print(f"{lat} {lon} {alt}") mocked_node.setFixedPosition.side_effect = mock_setFixedPosition iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Fixing altitude", out, re.MULTILINE) assert re.search(r"Setting device position", out, re.MULTILINE) assert re.search(r"inside mocked setFixedPosition", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_setlat(capsys)
-
Test –setlat
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_setlat(capsys): """Test --setlat""" sys.argv = ["", "--setlat", "37.5"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) def mock_setFixedPosition(lat, lon, alt): print("inside mocked setFixedPosition") print(f"{lat} {lon} {alt}") mocked_node.setFixedPosition.side_effect = mock_setFixedPosition iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Fixing latitude", out, re.MULTILINE) assert re.search(r"Setting device position", out, re.MULTILINE) assert re.search(r"inside mocked setFixedPosition", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_setlat_remote(capsys)
-
Test –setlat with a remote dest
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_setlat_remote(capsys): """Test --setlat with a remote dest""" sys.argv = ["", "--setlat", "37.5", "--dest", "!12345678"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Setting device position and enabling fixed position setting", out, re.MULTILINE) assert re.search(r"Waiting for an acknowledgment from remote node", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_setlon(capsys)
-
Test –setlon
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_setlon(capsys): """Test --setlon""" sys.argv = ["", "--setlon", "-122.1"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) def mock_setFixedPosition(lat, lon, alt): print("inside mocked setFixedPosition") print(f"{lat} {lon} {alt}") mocked_node.setFixedPosition.side_effect = mock_setFixedPosition iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"Fixing longitude", out, re.MULTILINE) assert re.search(r"Setting device position", out, re.MULTILINE) assert re.search(r"inside mocked setFixedPosition", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_seturl(capsys)
-
Test –seturl (url used below is what is generated after a factory_reset)
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_seturl(capsys): """Test --seturl (url used below is what is generated after a factory_reset)""" sys.argv = ["", "--seturl", "https://www.meshtastic.org/d/#CgUYAyIBAQ"] mt_config.args = sys.argv iface = MagicMock(autospec=SerialInterface) with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_shutdown(capsys)
-
Test –shutdown
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_shutdown(capsys): """Test --shutdown""" sys.argv = ["", "--shutdown"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) def mock_shutdown(): print("inside mocked shutdown") mocked_node.shutdown.side_effect = mock_shutdown iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo: main() out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert re.search(r"inside mocked shutdown", out, re.MULTILINE) assert err == "" mo.assert_called()
def test_main_support(capsys)
-
Test –support
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_main_support(capsys): """Test --support""" sys.argv = ["", "--support"] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 0 out, err = capsys.readouterr() assert re.search(r"System", out, re.MULTILINE) assert re.search(r"Platform", out, re.MULTILINE) assert re.search(r"Machine", out, re.MULTILINE) assert re.search(r"Executable", out, re.MULTILINE) assert err == ""
def test_main_test_no_ports(patched_find_ports, capsys)
-
Test –test with no hardware
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("meshtastic.util.findPorts", return_value=[]) def test_main_test_no_ports(patched_find_ports, capsys): """Test --test with no hardware""" sys.argv = ["", "--test"] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 patched_find_ports.assert_called() out, err = capsys.readouterr() assert re.search( r"Warning: Must have at least two devices connected to USB", out, re.MULTILINE ) assert err == ""
def test_main_test_one_port(patched_find_ports, capsys)
-
Test –test with one fake port
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyFake1"]) def test_main_test_one_port(patched_find_ports, capsys): """Test --test with one fake port""" sys.argv = ["", "--test"] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 patched_find_ports.assert_called() out, err = capsys.readouterr() assert re.search( r"Warning: Must have at least two devices connected to USB", out, re.MULTILINE ) assert err == ""
def test_main_test_two_ports_fails(patched_test_all, capsys)
-
Test –test two fake ports and testAll() is a simulated failure
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("meshtastic.test.testAll", return_value=False) def test_main_test_two_ports_fails(patched_test_all, capsys): """Test --test two fake ports and testAll() is a simulated failure""" sys.argv = ["", "--test"] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 patched_test_all.assert_called() out, err = capsys.readouterr() assert re.search(r"Test was not successful.", out, re.MULTILINE) assert err == ""
def test_main_test_two_ports_success(patched_test_all, capsys)
-
Test –test two fake ports and testAll() is a simulated success
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("meshtastic.test.testAll", return_value=True) def test_main_test_two_ports_success(patched_test_all, capsys): """Test --test two fake ports and testAll() is a simulated success""" sys.argv = ["", "--test"] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 0 patched_test_all.assert_called() out, err = capsys.readouterr() assert re.search(r"Test was a success.", out, re.MULTILINE) assert err == ""
def test_onNode(capsys)
-
Test onNode
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_onNode(capsys): """Test onNode""" onNode("foo") out, err = capsys.readouterr() assert re.search(r"Node changed", out, re.MULTILINE) assert err == ""
def test_remove_favorite_node()
-
Test –remove-favorite-node node
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_remove_favorite_node(): """Test --remove-favorite-node node""" sys.argv = ["", "--remove-favorite-node", "!12345678"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node mocked_node.iface = iface with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): main() mocked_node.removeFavorite.assert_called_once_with("!12345678")
def test_remove_ignored_node()
-
Test –remove-ignored-node node
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_remove_ignored_node(): """Test --remove-ignored-node node""" sys.argv = ["", "--remove-ignored-node", "!12345678"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node mocked_node.iface = iface with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): main() mocked_node.removeIgnored.assert_called_once_with("!12345678")
def test_set_favorite_node()
-
Test –set-favorite-node node
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_set_favorite_node(): """Test --set-favorite-node node""" sys.argv = ["", "--set-favorite-node", "!12345678"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): main() mocked_node.setFavorite.assert_called_once_with("!12345678")
def test_set_ignored_node()
-
Test –set-ignored-node node
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_set_ignored_node(): """Test --set-ignored-node node""" sys.argv = ["", "--set-ignored-node", "!12345678"] mt_config.args = sys.argv mocked_node = MagicMock(autospec=Node) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): main() mocked_node.setIgnored.assert_called_once_with("!12345678")
def test_tunnel_no_args(capsys)
-
Test tunnel no arguments
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_tunnel_no_args(capsys): """Test tunnel no arguments""" sys.argv = [""] mt_config.args = sys.argv with pytest.raises(SystemExit) as pytest_wrapped_e: tunnelMain() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 _, err = capsys.readouterr() assert re.search(r"usage: ", err, re.MULTILINE)
def test_tunnel_subnet_arg_with_no_devices(mock_platform_system, caplog, capsys)
-
Test tunnel with subnet arg (act like we are on a linux system)
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("meshtastic.util.findPorts", return_value=[]) @patch("platform.system") def test_tunnel_subnet_arg_with_no_devices(mock_platform_system, caplog, capsys): """Test tunnel with subnet arg (act like we are on a linux system)""" a_mock = MagicMock() a_mock.return_value = "Linux" mock_platform_system.side_effect = a_mock sys.argv = ["", "--subnet", "foo"] mt_config.args = sys.argv print(f"platform.system():{platform.system()}") with caplog.at_level(logging.DEBUG): with pytest.raises(SystemExit) as pytest_wrapped_e: tunnelMain() mock_platform_system.assert_called() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"No.*Meshtastic.*device.*detected", out, re.MULTILINE) assert err == ""
def test_tunnel_tunnel_arg(mocked_findPorts, mocked_serial, mocked_open, mock_get, mock_set, mock_platform_system, caplog, iface_with_nodes, capsys)
-
Test tunnel with tunnel arg (act like we are on a linux system)
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("platform.system") @patch("termios.tcsetattr") @patch("termios.tcgetattr") @patch("builtins.open", new_callable=mock_open, read_data="data") @patch("serial.Serial") @patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"]) def test_tunnel_tunnel_arg( mocked_findPorts, mocked_serial, mocked_open, mock_get, mock_set, mock_platform_system, caplog, iface_with_nodes, capsys ): """Test tunnel with tunnel arg (act like we are on a linux system)""" # Override the time.sleep so there is no loop def my_sleep(amount): print(f"{amount}") sys.exit(3) a_mock = MagicMock() a_mock.return_value = "Linux" mock_platform_system.side_effect = a_mock sys.argv = ["", "--tunnel"] mt_config.args = sys.argv serialInterface = SerialInterface(noProto=True) with caplog.at_level(logging.DEBUG): with patch("meshtastic.serial_interface.SerialInterface", return_value=serialInterface): with patch("time.sleep", side_effect=my_sleep): with pytest.raises(SystemExit) as pytest_wrapped_e: tunnelMain() mock_platform_system.assert_called() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 3 assert re.search(r"Not starting Tunnel", caplog.text, re.MULTILINE) out, err = capsys.readouterr() assert re.search(r"Connected to radio", out, re.MULTILINE) assert err == ""
def test_tunnel_tunnel_arg_with_no_devices(mock_platform_system, caplog, capsys)
-
Test tunnel with tunnel arg (act like we are on a linux system)
Expand source code
@pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @patch("meshtastic.util.findPorts", return_value=[]) @patch("platform.system") def test_tunnel_tunnel_arg_with_no_devices(mock_platform_system, caplog, capsys): """Test tunnel with tunnel arg (act like we are on a linux system)""" a_mock = MagicMock() a_mock.return_value = "Linux" mock_platform_system.side_effect = a_mock sys.argv = ["", "--tunnel"] mt_config.args = sys.argv print(f"platform.system():{platform.system()}") with caplog.at_level(logging.DEBUG): with pytest.raises(SystemExit) as pytest_wrapped_e: tunnelMain() mock_platform_system.assert_called() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.search(r"No.*Meshtastic.*device.*detected", out, re.MULTILINE) assert err == ""