Module meshtastic.tests.test_mesh_interface
Meshtastic unit tests for mesh_interface.py
Expand source code
"""Meshtastic unit tests for mesh_interface.py"""
import re
import logging
from unittest.mock import patch, MagicMock
import pytest
from ..mesh_interface import MeshInterface
from ..node import Node
from .. import mesh_pb2
from ..__init__ import LOCAL_ADDR, BROADCAST_ADDR
@pytest.mark.unit
def test_MeshInterface(capsys, reset_globals):
"""Test that we can instantiate a MeshInterface"""
iface = MeshInterface(noProto=True)
anode = Node('foo', 'bar')
nodes = {
'!9388f81c': {
'num': 2475227164,
'user': {
'id': '!9388f81c',
'longName': 'Unknown f81c',
'shortName': '?1C',
'macaddr': 'RBeTiPgc',
'hwModel': 'TBEAM'
},
'position': {},
'lastHeard': 1640204888
}
}
iface.nodesByNum = {1: anode }
iface.nodes = nodes
myInfo = MagicMock()
iface.myInfo = myInfo
iface.showInfo()
iface.localNode.showInfo()
iface.showNodes()
iface.sendText('hello')
iface.close()
out, err = capsys.readouterr()
assert re.search(r'Owner: None \(None\)', out, re.MULTILINE)
assert re.search(r'Nodes', out, re.MULTILINE)
assert re.search(r'Preferences', out, re.MULTILINE)
assert re.search(r'Channels', out, re.MULTILINE)
assert re.search(r'Primary channel URL', out, re.MULTILINE)
assert err == ''
@pytest.mark.unit
def test_getMyUser(reset_globals, iface_with_nodes):
"""Test getMyUser()"""
iface = iface_with_nodes
iface.myInfo.my_node_num = 2475227164
myuser = iface.getMyUser()
print(f'myuser:{myuser}')
assert myuser is not None
assert myuser["id"] == '!9388f81c'
@pytest.mark.unit
def test_getLongName(reset_globals, iface_with_nodes):
"""Test getLongName()"""
iface = iface_with_nodes
iface.myInfo.my_node_num = 2475227164
mylongname = iface.getLongName()
assert mylongname == 'Unknown f81c'
@pytest.mark.unit
def test_getShortName(reset_globals, iface_with_nodes):
"""Test getShortName()."""
iface = iface_with_nodes
iface.myInfo.my_node_num = 2475227164
myshortname = iface.getShortName()
assert myshortname == '?1C'
@pytest.mark.unit
def test_handlePacketFromRadio_no_from(capsys, reset_globals):
"""Test _handlePacketFromRadio with no 'from' in the mesh packet."""
iface = MeshInterface(noProto=True)
meshPacket = mesh_pb2.MeshPacket()
iface._handlePacketFromRadio(meshPacket)
out, err = capsys.readouterr()
assert re.search(r'Device returned a packet we sent, ignoring', out, re.MULTILINE)
assert err == ''
@pytest.mark.unit
def test_handlePacketFromRadio_with_a_portnum(caplog, reset_globals):
"""Test _handlePacketFromRadio with a portnum
Since we have an attribute called 'from', we cannot simply 'set' it.
Had to implement a hack just to be able to test some code.
"""
iface = MeshInterface(noProto=True)
meshPacket = mesh_pb2.MeshPacket()
meshPacket.decoded.payload = b''
meshPacket.decoded.portnum = 1
with caplog.at_level(logging.WARNING):
iface._handlePacketFromRadio(meshPacket, hack=True)
assert re.search(r'Not populating fromId', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_handlePacketFromRadio_no_portnum(caplog, reset_globals):
"""Test _handlePacketFromRadio without a portnum"""
iface = MeshInterface(noProto=True)
meshPacket = mesh_pb2.MeshPacket()
meshPacket.decoded.payload = b''
with caplog.at_level(logging.WARNING):
iface._handlePacketFromRadio(meshPacket, hack=True)
assert re.search(r'Not populating fromId', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_getNode_with_local(reset_globals):
"""Test getNode"""
iface = MeshInterface(noProto=True)
anode = iface.getNode(LOCAL_ADDR)
assert anode == iface.localNode
@pytest.mark.unit
def test_getNode_not_local(reset_globals, caplog):
"""Test getNode not local"""
iface = MeshInterface(noProto=True)
anode = MagicMock(autospec=Node)
with caplog.at_level(logging.DEBUG):
with patch('meshtastic.node.Node', return_value=anode):
another_node = iface.getNode('bar2')
assert another_node != iface.localNode
assert re.search(r'About to requestConfig', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_getNode_not_local_timeout(reset_globals, capsys):
"""Test getNode not local, simulate timeout"""
iface = MeshInterface(noProto=True)
anode = MagicMock(autospec=Node)
anode.waitForConfig.return_value = False
with patch('meshtastic.node.Node', return_value=anode):
with pytest.raises(SystemExit) as pytest_wrapped_e:
iface.getNode('bar2')
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.match(r'Error: Timed out waiting for node config', out)
assert err == ''
@pytest.mark.unit
def test_sendPosition(reset_globals, caplog):
"""Test sendPosition"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface.sendPosition()
iface.close()
assert re.search(r'p.time:', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_handleFromRadio_empty_payload(reset_globals, caplog):
"""Test _handleFromRadio"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface._handleFromRadio(b'')
iface.close()
assert re.search(r'Unexpected FromRadio payload', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_handleFromRadio_with_my_info(reset_globals, caplog):
"""Test _handleFromRadio with my_info"""
# Note: I captured the '--debug --info' for the bytes below.
# It "translates" to this:
# my_info {
# my_node_num: 682584012
# num_bands: 13
# firmware_version: "1.2.49.5354c49"
# reboot_count: 13
# bitrate: 17.088470458984375
# message_timeout_msec: 300000
# min_app_version: 20200
# max_channels: 8
# }
from_radio_bytes = b'\x1a,\x08\xcc\xcf\xbd\xc5\x02\x18\r2\x0e1.2.49.5354c49P\r]0\xb5\x88Ah\xe0\xa7\x12p\xe8\x9d\x01x\x08\x90\x01\x01'
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface._handleFromRadio(from_radio_bytes)
iface.close()
assert re.search(r'Received myinfo', caplog.text, re.MULTILINE)
assert re.search(r'num_bands: 13', caplog.text, re.MULTILINE)
assert re.search(r'max_channels: 8', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_handleFromRadio_with_node_info(reset_globals, caplog, capsys):
"""Test _handleFromRadio with node_info"""
# Note: I captured the '--debug --info' for the bytes below.
# It "translates" to this:
# node_info {
# num: 682584012
# user {
# id: "!28af67cc"
# long_name: "Unknown 67cc"
# short_name: "?CC"
# macaddr: "$o(\257g\314"
# hw_model: HELTEC_V2_1
# }
# position {
# }
# }
from_radio_bytes = b'"2\x08\xcc\xcf\xbd\xc5\x02\x12(\n\t!28af67cc\x12\x0cUnknown 67cc\x1a\x03?CC"\x06$o(\xafg\xcc0\n\x1a\x00'
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface._startConfig()
iface._handleFromRadio(from_radio_bytes)
assert re.search(r'Received nodeinfo', caplog.text, re.MULTILINE)
assert re.search(r'682584012', caplog.text, re.MULTILINE)
assert re.search(r'HELTEC_V2_1', caplog.text, re.MULTILINE)
# validate some of showNodes() output
iface.showNodes()
out, err = capsys.readouterr()
assert re.search(r' 1 ', out, re.MULTILINE)
assert re.search(r'│ Unknown 67cc │ ', out, re.MULTILINE)
assert re.search(r'│ !28af67cc │ N/A │ N/A │ N/A', out, re.MULTILINE)
assert err == ''
iface.close()
@pytest.mark.unit
def test_handleFromRadio_with_node_info_tbeam1(reset_globals, caplog, capsys):
"""Test _handleFromRadio with node_info"""
# Note: Captured the '--debug --info' for the bytes below.
# pylint: disable=C0301
from_radio_bytes = b'"=\x08\x80\xf8\xc8\xf6\x07\x12"\n\t!7ed23c00\x12\x07TBeam 1\x1a\x02T1"\x06\x94\xb9~\xd2<\x000\x04\x1a\x07 ]MN\x01\xbea%\xad\x01\xbea=\x00\x00,A'
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface._startConfig()
iface._handleFromRadio(from_radio_bytes)
assert re.search(r'Received nodeinfo', caplog.text, re.MULTILINE)
assert re.search(r'TBeam 1', caplog.text, re.MULTILINE)
assert re.search(r'2127707136', caplog.text, re.MULTILINE)
# validate some of showNodes() output
iface.showNodes()
out, err = capsys.readouterr()
assert re.search(r' 1 ', out, re.MULTILINE)
assert re.search(r'│ TBeam 1 │ ', out, re.MULTILINE)
assert re.search(r'│ !7ed23c00 │', out, re.MULTILINE)
assert err == ''
iface.close()
@pytest.mark.unit
def test_handleFromRadio_with_node_info_tbeam_with_bad_data(reset_globals, caplog, capsys):
"""Test _handleFromRadio with node_info with some bad data (issue#172) - ensure we do not throw exception"""
# Note: Captured the '--debug --info' for the bytes below.
from_radio_bytes = b'"\x17\x08\xdc\x8a\x8a\xae\x02\x12\x08"\x06\x00\x00\x00\x00\x00\x00\x1a\x00=\x00\x00\xb8@'
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface._startConfig()
iface._handleFromRadio(from_radio_bytes)
@pytest.mark.unit
def test_MeshInterface_sendToRadioImpl(caplog, reset_globals):
"""Test _sendToRadioImp()"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface._sendToRadioImpl('foo')
assert re.search(r'Subclass must provide toradio', caplog.text, re.MULTILINE)
iface.close()
@pytest.mark.unit
def test_MeshInterface_sendToRadio_no_proto(caplog, reset_globals):
"""Test sendToRadio()"""
iface = MeshInterface()
with caplog.at_level(logging.DEBUG):
iface._sendToRadioImpl('foo')
assert re.search(r'Subclass must provide toradio', caplog.text, re.MULTILINE)
iface.close()
@pytest.mark.unit
def test_sendData_too_long(caplog, reset_globals):
"""Test when data payload is too big"""
iface = MeshInterface(noProto=True)
some_large_text = b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
some_large_text += b'This is a long text that will be too long for send text.'
with caplog.at_level(logging.DEBUG):
with pytest.raises(Exception) as pytest_wrapped_e:
iface.sendData(some_large_text)
assert re.search('Data payload too big', caplog.text, re.MULTILINE)
assert pytest_wrapped_e.type == Exception
iface.close()
@pytest.mark.unit
def test_sendData_unknown_app(capsys, reset_globals):
"""Test sendData when unknown app"""
iface = MeshInterface(noProto=True)
with pytest.raises(SystemExit) as pytest_wrapped_e:
iface.sendData(b'hello', portNum=0)
out, err = capsys.readouterr()
assert re.search(r'Warning: A non-zero port number', out, re.MULTILINE)
assert err == ''
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
@pytest.mark.unit
def test_sendPosition_with_a_position(caplog, reset_globals):
"""Test sendPosition when lat/long/alt"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface.sendPosition(latitude=40.8, longitude=-111.86, altitude=201)
assert re.search(r'p.latitude_i:408', caplog.text, re.MULTILINE)
assert re.search(r'p.longitude_i:-11186', caplog.text, re.MULTILINE)
assert re.search(r'p.altitude:201', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_sendPacket_with_no_destination(capsys, reset_globals):
"""Test _sendPacket()"""
iface = MeshInterface(noProto=True)
with pytest.raises(SystemExit) as pytest_wrapped_e:
iface._sendPacket(b'', destinationId=None)
out, err = capsys.readouterr()
assert re.search(r'Warning: destinationId must not be None', out, re.MULTILINE)
assert err == ''
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
@pytest.mark.unit
def test_sendPacket_with_destination_as_int(caplog, reset_globals):
"""Test _sendPacket() with int as a destination"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
meshPacket = mesh_pb2.MeshPacket()
iface._sendPacket(meshPacket, destinationId=123)
assert re.search(r'Not sending packet', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_sendPacket_with_destination_starting_with_a_bang(caplog, reset_globals):
"""Test _sendPacket() with int as a destination"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
meshPacket = mesh_pb2.MeshPacket()
iface._sendPacket(meshPacket, destinationId='!1234')
assert re.search(r'Not sending packet', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_sendPacket_with_destination_as_BROADCAST_ADDR(caplog, reset_globals):
"""Test _sendPacket() with BROADCAST_ADDR as a destination"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
meshPacket = mesh_pb2.MeshPacket()
iface._sendPacket(meshPacket, destinationId=BROADCAST_ADDR)
assert re.search(r'Not sending packet', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_sendPacket_with_destination_as_LOCAL_ADDR_no_myInfo(capsys, reset_globals):
"""Test _sendPacket() with LOCAL_ADDR as a destination with no myInfo"""
iface = MeshInterface(noProto=True)
with pytest.raises(SystemExit) as pytest_wrapped_e:
meshPacket = mesh_pb2.MeshPacket()
iface._sendPacket(meshPacket, destinationId=LOCAL_ADDR)
out, err = capsys.readouterr()
assert re.search(r'Warning: No myInfo', out, re.MULTILINE)
assert err == ''
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
@pytest.mark.unit
def test_sendPacket_with_destination_as_LOCAL_ADDR_with_myInfo(caplog, reset_globals):
"""Test _sendPacket() with LOCAL_ADDR as a destination with myInfo"""
iface = MeshInterface(noProto=True)
myInfo = MagicMock()
iface.myInfo = myInfo
with caplog.at_level(logging.DEBUG):
meshPacket = mesh_pb2.MeshPacket()
iface._sendPacket(meshPacket, destinationId=LOCAL_ADDR)
assert re.search(r'Not sending packet', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_sendPacket_with_destination_is_blank_with_nodes(capsys, reset_globals, iface_with_nodes):
"""Test _sendPacket() with '' as a destination with myInfo"""
iface = iface_with_nodes
meshPacket = mesh_pb2.MeshPacket()
with pytest.raises(SystemExit) as pytest_wrapped_e:
iface._sendPacket(meshPacket, destinationId='')
assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 1
out, err = capsys.readouterr()
assert re.match(r'Warning: NodeId not found in DB', out, re.MULTILINE)
assert err == ''
@pytest.mark.unit
def test_sendPacket_with_destination_is_blank_without_nodes(caplog, reset_globals, iface_with_nodes):
"""Test _sendPacket() with '' as a destination with myInfo"""
iface = iface_with_nodes
iface.nodes = None
meshPacket = mesh_pb2.MeshPacket()
with caplog.at_level(logging.WARNING):
iface._sendPacket(meshPacket, destinationId='')
assert re.search(r'Warning: There were no self.nodes.', caplog.text, re.MULTILINE)
@pytest.mark.unit
def test_getMyNodeInfo(reset_globals):
"""Test getMyNodeInfo()"""
iface = MeshInterface(noProto=True)
anode = iface.getNode(LOCAL_ADDR)
iface.nodesByNum = {1: anode }
assert iface.nodesByNum.get(1) == anode
myInfo = MagicMock()
iface.myInfo = myInfo
iface.myInfo.my_node_num = 1
myinfo = iface.getMyNodeInfo()
assert myinfo == anode
@pytest.mark.unit
def test_generatePacketId(capsys, reset_globals):
"""Test _generatePacketId() when no currentPacketId (not connected)"""
iface = MeshInterface(noProto=True)
# not sure when this condition would ever happen... but we can simulate it
iface.currentPacketId = None
assert iface.currentPacketId is None
with pytest.raises(Exception) as pytest_wrapped_e:
iface._generatePacketId()
out, err = capsys.readouterr()
assert re.search(r'Not connected yet, can not generate packet', out, re.MULTILINE)
assert err == ''
assert pytest_wrapped_e.type == Exception
Functions
def test_MeshInterface(capsys, reset_globals)-
Test that we can instantiate a MeshInterface
Expand source code
@pytest.mark.unit def test_MeshInterface(capsys, reset_globals): """Test that we can instantiate a MeshInterface""" iface = MeshInterface(noProto=True) anode = Node('foo', 'bar') nodes = { '!9388f81c': { 'num': 2475227164, 'user': { 'id': '!9388f81c', 'longName': 'Unknown f81c', 'shortName': '?1C', 'macaddr': 'RBeTiPgc', 'hwModel': 'TBEAM' }, 'position': {}, 'lastHeard': 1640204888 } } iface.nodesByNum = {1: anode } iface.nodes = nodes myInfo = MagicMock() iface.myInfo = myInfo iface.showInfo() iface.localNode.showInfo() iface.showNodes() iface.sendText('hello') iface.close() out, err = capsys.readouterr() assert re.search(r'Owner: None \(None\)', out, re.MULTILINE) assert re.search(r'Nodes', out, re.MULTILINE) assert re.search(r'Preferences', out, re.MULTILINE) assert re.search(r'Channels', out, re.MULTILINE) assert re.search(r'Primary channel URL', out, re.MULTILINE) assert err == '' def test_MeshInterface_sendToRadioImpl(caplog, reset_globals)-
Test _sendToRadioImp()
Expand source code
@pytest.mark.unit def test_MeshInterface_sendToRadioImpl(caplog, reset_globals): """Test _sendToRadioImp()""" iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): iface._sendToRadioImpl('foo') assert re.search(r'Subclass must provide toradio', caplog.text, re.MULTILINE) iface.close() def test_MeshInterface_sendToRadio_no_proto(caplog, reset_globals)-
Test sendToRadio()
Expand source code
@pytest.mark.unit def test_MeshInterface_sendToRadio_no_proto(caplog, reset_globals): """Test sendToRadio()""" iface = MeshInterface() with caplog.at_level(logging.DEBUG): iface._sendToRadioImpl('foo') assert re.search(r'Subclass must provide toradio', caplog.text, re.MULTILINE) iface.close() def test_generatePacketId(capsys, reset_globals)-
Test _generatePacketId() when no currentPacketId (not connected)
Expand source code
@pytest.mark.unit def test_generatePacketId(capsys, reset_globals): """Test _generatePacketId() when no currentPacketId (not connected)""" iface = MeshInterface(noProto=True) # not sure when this condition would ever happen... but we can simulate it iface.currentPacketId = None assert iface.currentPacketId is None with pytest.raises(Exception) as pytest_wrapped_e: iface._generatePacketId() out, err = capsys.readouterr() assert re.search(r'Not connected yet, can not generate packet', out, re.MULTILINE) assert err == '' assert pytest_wrapped_e.type == Exception def test_getLongName(reset_globals, iface_with_nodes)-
Test getLongName()
Expand source code
@pytest.mark.unit def test_getLongName(reset_globals, iface_with_nodes): """Test getLongName()""" iface = iface_with_nodes iface.myInfo.my_node_num = 2475227164 mylongname = iface.getLongName() assert mylongname == 'Unknown f81c' def test_getMyNodeInfo(reset_globals)-
Test getMyNodeInfo()
Expand source code
@pytest.mark.unit def test_getMyNodeInfo(reset_globals): """Test getMyNodeInfo()""" iface = MeshInterface(noProto=True) anode = iface.getNode(LOCAL_ADDR) iface.nodesByNum = {1: anode } assert iface.nodesByNum.get(1) == anode myInfo = MagicMock() iface.myInfo = myInfo iface.myInfo.my_node_num = 1 myinfo = iface.getMyNodeInfo() assert myinfo == anode def test_getMyUser(reset_globals, iface_with_nodes)-
Test getMyUser()
Expand source code
@pytest.mark.unit def test_getMyUser(reset_globals, iface_with_nodes): """Test getMyUser()""" iface = iface_with_nodes iface.myInfo.my_node_num = 2475227164 myuser = iface.getMyUser() print(f'myuser:{myuser}') assert myuser is not None assert myuser["id"] == '!9388f81c' def test_getNode_not_local(reset_globals, caplog)-
Test getNode not local
Expand source code
@pytest.mark.unit def test_getNode_not_local(reset_globals, caplog): """Test getNode not local""" iface = MeshInterface(noProto=True) anode = MagicMock(autospec=Node) with caplog.at_level(logging.DEBUG): with patch('meshtastic.node.Node', return_value=anode): another_node = iface.getNode('bar2') assert another_node != iface.localNode assert re.search(r'About to requestConfig', caplog.text, re.MULTILINE) def test_getNode_not_local_timeout(reset_globals, capsys)-
Test getNode not local, simulate timeout
Expand source code
@pytest.mark.unit def test_getNode_not_local_timeout(reset_globals, capsys): """Test getNode not local, simulate timeout""" iface = MeshInterface(noProto=True) anode = MagicMock(autospec=Node) anode.waitForConfig.return_value = False with patch('meshtastic.node.Node', return_value=anode): with pytest.raises(SystemExit) as pytest_wrapped_e: iface.getNode('bar2') assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.match(r'Error: Timed out waiting for node config', out) assert err == '' def test_getNode_with_local(reset_globals)-
Test getNode
Expand source code
@pytest.mark.unit def test_getNode_with_local(reset_globals): """Test getNode""" iface = MeshInterface(noProto=True) anode = iface.getNode(LOCAL_ADDR) assert anode == iface.localNode def test_getShortName(reset_globals, iface_with_nodes)-
Test getShortName().
Expand source code
@pytest.mark.unit def test_getShortName(reset_globals, iface_with_nodes): """Test getShortName().""" iface = iface_with_nodes iface.myInfo.my_node_num = 2475227164 myshortname = iface.getShortName() assert myshortname == '?1C' def test_handleFromRadio_empty_payload(reset_globals, caplog)-
Test _handleFromRadio
Expand source code
@pytest.mark.unit def test_handleFromRadio_empty_payload(reset_globals, caplog): """Test _handleFromRadio""" iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): iface._handleFromRadio(b'') iface.close() assert re.search(r'Unexpected FromRadio payload', caplog.text, re.MULTILINE) def test_handleFromRadio_with_my_info(reset_globals, caplog)-
Test _handleFromRadio with my_info
Expand source code
@pytest.mark.unit def test_handleFromRadio_with_my_info(reset_globals, caplog): """Test _handleFromRadio with my_info""" # Note: I captured the '--debug --info' for the bytes below. # It "translates" to this: # my_info { # my_node_num: 682584012 # num_bands: 13 # firmware_version: "1.2.49.5354c49" # reboot_count: 13 # bitrate: 17.088470458984375 # message_timeout_msec: 300000 # min_app_version: 20200 # max_channels: 8 # } from_radio_bytes = b'\x1a,\x08\xcc\xcf\xbd\xc5\x02\x18\r2\x0e1.2.49.5354c49P\r]0\xb5\x88Ah\xe0\xa7\x12p\xe8\x9d\x01x\x08\x90\x01\x01' iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): iface._handleFromRadio(from_radio_bytes) iface.close() assert re.search(r'Received myinfo', caplog.text, re.MULTILINE) assert re.search(r'num_bands: 13', caplog.text, re.MULTILINE) assert re.search(r'max_channels: 8', caplog.text, re.MULTILINE) def test_handleFromRadio_with_node_info(reset_globals, caplog, capsys)-
Test _handleFromRadio with node_info
Expand source code
@pytest.mark.unit def test_handleFromRadio_with_node_info(reset_globals, caplog, capsys): """Test _handleFromRadio with node_info""" # Note: I captured the '--debug --info' for the bytes below. # It "translates" to this: # node_info { # num: 682584012 # user { # id: "!28af67cc" # long_name: "Unknown 67cc" # short_name: "?CC" # macaddr: "$o(\257g\314" # hw_model: HELTEC_V2_1 # } # position { # } # } from_radio_bytes = b'"2\x08\xcc\xcf\xbd\xc5\x02\x12(\n\t!28af67cc\x12\x0cUnknown 67cc\x1a\x03?CC"\x06$o(\xafg\xcc0\n\x1a\x00' iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): iface._startConfig() iface._handleFromRadio(from_radio_bytes) assert re.search(r'Received nodeinfo', caplog.text, re.MULTILINE) assert re.search(r'682584012', caplog.text, re.MULTILINE) assert re.search(r'HELTEC_V2_1', caplog.text, re.MULTILINE) # validate some of showNodes() output iface.showNodes() out, err = capsys.readouterr() assert re.search(r' 1 ', out, re.MULTILINE) assert re.search(r'│ Unknown 67cc │ ', out, re.MULTILINE) assert re.search(r'│ !28af67cc │ N/A │ N/A │ N/A', out, re.MULTILINE) assert err == '' iface.close() def test_handleFromRadio_with_node_info_tbeam1(reset_globals, caplog, capsys)-
Test _handleFromRadio with node_info
Expand source code
@pytest.mark.unit def test_handleFromRadio_with_node_info_tbeam1(reset_globals, caplog, capsys): """Test _handleFromRadio with node_info""" # Note: Captured the '--debug --info' for the bytes below. # pylint: disable=C0301 from_radio_bytes = b'"=\x08\x80\xf8\xc8\xf6\x07\x12"\n\t!7ed23c00\x12\x07TBeam 1\x1a\x02T1"\x06\x94\xb9~\xd2<\x000\x04\x1a\x07 ]MN\x01\xbea%\xad\x01\xbea=\x00\x00,A' iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): iface._startConfig() iface._handleFromRadio(from_radio_bytes) assert re.search(r'Received nodeinfo', caplog.text, re.MULTILINE) assert re.search(r'TBeam 1', caplog.text, re.MULTILINE) assert re.search(r'2127707136', caplog.text, re.MULTILINE) # validate some of showNodes() output iface.showNodes() out, err = capsys.readouterr() assert re.search(r' 1 ', out, re.MULTILINE) assert re.search(r'│ TBeam 1 │ ', out, re.MULTILINE) assert re.search(r'│ !7ed23c00 │', out, re.MULTILINE) assert err == '' iface.close() def test_handleFromRadio_with_node_info_tbeam_with_bad_data(reset_globals, caplog, capsys)-
Test _handleFromRadio with node_info with some bad data (issue#172) - ensure we do not throw exception
Expand source code
@pytest.mark.unit def test_handleFromRadio_with_node_info_tbeam_with_bad_data(reset_globals, caplog, capsys): """Test _handleFromRadio with node_info with some bad data (issue#172) - ensure we do not throw exception""" # Note: Captured the '--debug --info' for the bytes below. from_radio_bytes = b'"\x17\x08\xdc\x8a\x8a\xae\x02\x12\x08"\x06\x00\x00\x00\x00\x00\x00\x1a\x00=\x00\x00\xb8@' iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): iface._startConfig() iface._handleFromRadio(from_radio_bytes) def test_handlePacketFromRadio_no_from(capsys, reset_globals)-
Test _handlePacketFromRadio with no 'from' in the mesh packet.
Expand source code
@pytest.mark.unit def test_handlePacketFromRadio_no_from(capsys, reset_globals): """Test _handlePacketFromRadio with no 'from' in the mesh packet.""" iface = MeshInterface(noProto=True) meshPacket = mesh_pb2.MeshPacket() iface._handlePacketFromRadio(meshPacket) out, err = capsys.readouterr() assert re.search(r'Device returned a packet we sent, ignoring', out, re.MULTILINE) assert err == '' def test_handlePacketFromRadio_no_portnum(caplog, reset_globals)-
Test _handlePacketFromRadio without a portnum
Expand source code
@pytest.mark.unit def test_handlePacketFromRadio_no_portnum(caplog, reset_globals): """Test _handlePacketFromRadio without a portnum""" iface = MeshInterface(noProto=True) meshPacket = mesh_pb2.MeshPacket() meshPacket.decoded.payload = b'' with caplog.at_level(logging.WARNING): iface._handlePacketFromRadio(meshPacket, hack=True) assert re.search(r'Not populating fromId', caplog.text, re.MULTILINE) def test_handlePacketFromRadio_with_a_portnum(caplog, reset_globals)-
Test _handlePacketFromRadio with a portnum Since we have an attribute called 'from', we cannot simply 'set' it. Had to implement a hack just to be able to test some code.
Expand source code
@pytest.mark.unit def test_handlePacketFromRadio_with_a_portnum(caplog, reset_globals): """Test _handlePacketFromRadio with a portnum Since we have an attribute called 'from', we cannot simply 'set' it. Had to implement a hack just to be able to test some code. """ iface = MeshInterface(noProto=True) meshPacket = mesh_pb2.MeshPacket() meshPacket.decoded.payload = b'' meshPacket.decoded.portnum = 1 with caplog.at_level(logging.WARNING): iface._handlePacketFromRadio(meshPacket, hack=True) assert re.search(r'Not populating fromId', caplog.text, re.MULTILINE) def test_sendData_too_long(caplog, reset_globals)-
Test when data payload is too big
Expand source code
@pytest.mark.unit def test_sendData_too_long(caplog, reset_globals): """Test when data payload is too big""" iface = MeshInterface(noProto=True) some_large_text = b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' some_large_text += b'This is a long text that will be too long for send text.' with caplog.at_level(logging.DEBUG): with pytest.raises(Exception) as pytest_wrapped_e: iface.sendData(some_large_text) assert re.search('Data payload too big', caplog.text, re.MULTILINE) assert pytest_wrapped_e.type == Exception iface.close() def test_sendData_unknown_app(capsys, reset_globals)-
Test sendData when unknown app
Expand source code
@pytest.mark.unit def test_sendData_unknown_app(capsys, reset_globals): """Test sendData when unknown app""" iface = MeshInterface(noProto=True) with pytest.raises(SystemExit) as pytest_wrapped_e: iface.sendData(b'hello', portNum=0) out, err = capsys.readouterr() assert re.search(r'Warning: A non-zero port number', out, re.MULTILINE) assert err == '' assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 def test_sendPacket_with_destination_as_BROADCAST_ADDR(caplog, reset_globals)-
Test _sendPacket() with BROADCAST_ADDR as a destination
Expand source code
@pytest.mark.unit def test_sendPacket_with_destination_as_BROADCAST_ADDR(caplog, reset_globals): """Test _sendPacket() with BROADCAST_ADDR as a destination""" iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): meshPacket = mesh_pb2.MeshPacket() iface._sendPacket(meshPacket, destinationId=BROADCAST_ADDR) assert re.search(r'Not sending packet', caplog.text, re.MULTILINE) def test_sendPacket_with_destination_as_LOCAL_ADDR_no_myInfo(capsys, reset_globals)-
Test _sendPacket() with LOCAL_ADDR as a destination with no myInfo
Expand source code
@pytest.mark.unit def test_sendPacket_with_destination_as_LOCAL_ADDR_no_myInfo(capsys, reset_globals): """Test _sendPacket() with LOCAL_ADDR as a destination with no myInfo""" iface = MeshInterface(noProto=True) with pytest.raises(SystemExit) as pytest_wrapped_e: meshPacket = mesh_pb2.MeshPacket() iface._sendPacket(meshPacket, destinationId=LOCAL_ADDR) out, err = capsys.readouterr() assert re.search(r'Warning: No myInfo', out, re.MULTILINE) assert err == '' assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 def test_sendPacket_with_destination_as_LOCAL_ADDR_with_myInfo(caplog, reset_globals)-
Test _sendPacket() with LOCAL_ADDR as a destination with myInfo
Expand source code
@pytest.mark.unit def test_sendPacket_with_destination_as_LOCAL_ADDR_with_myInfo(caplog, reset_globals): """Test _sendPacket() with LOCAL_ADDR as a destination with myInfo""" iface = MeshInterface(noProto=True) myInfo = MagicMock() iface.myInfo = myInfo with caplog.at_level(logging.DEBUG): meshPacket = mesh_pb2.MeshPacket() iface._sendPacket(meshPacket, destinationId=LOCAL_ADDR) assert re.search(r'Not sending packet', caplog.text, re.MULTILINE) def test_sendPacket_with_destination_as_int(caplog, reset_globals)-
Test _sendPacket() with int as a destination
Expand source code
@pytest.mark.unit def test_sendPacket_with_destination_as_int(caplog, reset_globals): """Test _sendPacket() with int as a destination""" iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): meshPacket = mesh_pb2.MeshPacket() iface._sendPacket(meshPacket, destinationId=123) assert re.search(r'Not sending packet', caplog.text, re.MULTILINE) def test_sendPacket_with_destination_is_blank_with_nodes(capsys, reset_globals, iface_with_nodes)-
Test _sendPacket() with '' as a destination with myInfo
Expand source code
@pytest.mark.unit def test_sendPacket_with_destination_is_blank_with_nodes(capsys, reset_globals, iface_with_nodes): """Test _sendPacket() with '' as a destination with myInfo""" iface = iface_with_nodes meshPacket = mesh_pb2.MeshPacket() with pytest.raises(SystemExit) as pytest_wrapped_e: iface._sendPacket(meshPacket, destinationId='') assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() assert re.match(r'Warning: NodeId not found in DB', out, re.MULTILINE) assert err == '' def test_sendPacket_with_destination_is_blank_without_nodes(caplog, reset_globals, iface_with_nodes)-
Test _sendPacket() with '' as a destination with myInfo
Expand source code
@pytest.mark.unit def test_sendPacket_with_destination_is_blank_without_nodes(caplog, reset_globals, iface_with_nodes): """Test _sendPacket() with '' as a destination with myInfo""" iface = iface_with_nodes iface.nodes = None meshPacket = mesh_pb2.MeshPacket() with caplog.at_level(logging.WARNING): iface._sendPacket(meshPacket, destinationId='') assert re.search(r'Warning: There were no self.nodes.', caplog.text, re.MULTILINE) def test_sendPacket_with_destination_starting_with_a_bang(caplog, reset_globals)-
Test _sendPacket() with int as a destination
Expand source code
@pytest.mark.unit def test_sendPacket_with_destination_starting_with_a_bang(caplog, reset_globals): """Test _sendPacket() with int as a destination""" iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): meshPacket = mesh_pb2.MeshPacket() iface._sendPacket(meshPacket, destinationId='!1234') assert re.search(r'Not sending packet', caplog.text, re.MULTILINE) def test_sendPacket_with_no_destination(capsys, reset_globals)-
Test _sendPacket()
Expand source code
@pytest.mark.unit def test_sendPacket_with_no_destination(capsys, reset_globals): """Test _sendPacket()""" iface = MeshInterface(noProto=True) with pytest.raises(SystemExit) as pytest_wrapped_e: iface._sendPacket(b'', destinationId=None) out, err = capsys.readouterr() assert re.search(r'Warning: destinationId must not be None', out, re.MULTILINE) assert err == '' assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 def test_sendPosition(reset_globals, caplog)-
Test sendPosition
Expand source code
@pytest.mark.unit def test_sendPosition(reset_globals, caplog): """Test sendPosition""" iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): iface.sendPosition() iface.close() assert re.search(r'p.time:', caplog.text, re.MULTILINE) def test_sendPosition_with_a_position(caplog, reset_globals)-
Test sendPosition when lat/long/alt
Expand source code
@pytest.mark.unit def test_sendPosition_with_a_position(caplog, reset_globals): """Test sendPosition when lat/long/alt""" iface = MeshInterface(noProto=True) with caplog.at_level(logging.DEBUG): iface.sendPosition(latitude=40.8, longitude=-111.86, altitude=201) assert re.search(r'p.latitude_i:408', caplog.text, re.MULTILINE) assert re.search(r'p.longitude_i:-11186', caplog.text, re.MULTILINE) assert re.search(r'p.altitude:201', caplog.text, re.MULTILINE)