From 55e374c89be5b366c3e4117c330632d134f110fd Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Wed, 8 Dec 2021 23:20:20 -0800 Subject: [PATCH 1/6] add some tests --- meshtastic/test/test_mesh_interface.py | 4 ++-- meshtastic/test/test_stream_interface.py | 14 +++++++++++++ meshtastic/test/test_tcp_interface.py | 26 ++++++++++++++++++++++++ meshtastic/test/test_util.py | 2 +- 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 meshtastic/test/test_stream_interface.py create mode 100644 meshtastic/test/test_tcp_interface.py diff --git a/meshtastic/test/test_mesh_interface.py b/meshtastic/test/test_mesh_interface.py index 77a5608..5862141 100644 --- a/meshtastic/test/test_mesh_interface.py +++ b/meshtastic/test/test_mesh_interface.py @@ -1,4 +1,4 @@ -"""Meshtastic unit tests for node.py""" +"""Meshtastic unit tests for mesh_interface.py""" import re @@ -9,7 +9,7 @@ from meshtastic.mesh_interface import MeshInterface @pytest.mark.unit def test_MeshInterface(capsys): - """Test that we instantiate a MeshInterface""" + """Test that we can instantiate a MeshInterface""" iface = MeshInterface(noProto=True) iface.showInfo() iface.localNode.showInfo() diff --git a/meshtastic/test/test_stream_interface.py b/meshtastic/test/test_stream_interface.py new file mode 100644 index 0000000..2d051cb --- /dev/null +++ b/meshtastic/test/test_stream_interface.py @@ -0,0 +1,14 @@ +"""Meshtastic unit tests for stream_interface.py""" + + +import pytest + +from meshtastic.stream_interface import StreamInterface + + +@pytest.mark.unit +def test_StreamInterface(): + """Test that we can instantiate a StreamInterface""" + with pytest.raises(Exception) as pytest_wrapped_e: + StreamInterface(noProto=True) + assert pytest_wrapped_e.type == Exception diff --git a/meshtastic/test/test_tcp_interface.py b/meshtastic/test/test_tcp_interface.py new file mode 100644 index 0000000..aa35018 --- /dev/null +++ b/meshtastic/test/test_tcp_interface.py @@ -0,0 +1,26 @@ +"""Meshtastic unit tests for tcp_interface.py""" + +import re + +from unittest.mock import patch +import pytest + +from meshtastic.tcp_interface import TCPInterface + + +@pytest.mark.unit +def test_TCPInterface(capsys): + """Test that we can instantiate a TCPInterface""" + with patch('socket.socket') as mock_socket: + iface = TCPInterface(hostname='localhost', noProto=True) + iface.showInfo() + iface.localNode.showInfo() + 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 == '' + assert mock_socket.called + iface.close() diff --git a/meshtastic/test/test_util.py b/meshtastic/test/test_util.py index ea3253b..cf5f638 100644 --- a/meshtastic/test/test_util.py +++ b/meshtastic/test/test_util.py @@ -1,4 +1,4 @@ -"""Meshtastic unit tests for node.py""" +"""Meshtastic unit tests for util.py""" import re From af6c54db0820dd90acd3ea68956178069728e7f5 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Thu, 9 Dec 2021 00:26:28 -0800 Subject: [PATCH 2/6] change to relative importing --- meshtastic/test/test_mesh_interface.py | 2 +- meshtastic/test/test_smoke1.py | 4 ++-- meshtastic/test/test_stream_interface.py | 2 +- meshtastic/test/test_tcp_interface.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/meshtastic/test/test_mesh_interface.py b/meshtastic/test/test_mesh_interface.py index 5862141..325c17a 100644 --- a/meshtastic/test/test_mesh_interface.py +++ b/meshtastic/test/test_mesh_interface.py @@ -4,7 +4,7 @@ import re import pytest -from meshtastic.mesh_interface import MeshInterface +from ..mesh_interface import MeshInterface @pytest.mark.unit diff --git a/meshtastic/test/test_smoke1.py b/meshtastic/test/test_smoke1.py index 242604f..a7f4b00 100644 --- a/meshtastic/test/test_smoke1.py +++ b/meshtastic/test/test_smoke1.py @@ -8,7 +8,7 @@ import os # sense to pause for the radio at apprpriate times import pytest -import meshtastic +from ..util import findPorts # seconds to pause after running a meshtastic command PAUSE_AFTER_COMMAND = 2 @@ -143,7 +143,7 @@ def test_smoke1_send_hello(): def test_smoke1_port(): """Test --port""" # first, get the ports - ports = meshtastic.util.findPorts() + ports = findPorts() # hopefully there is just one assert len(ports) == 1 port = ports[0] diff --git a/meshtastic/test/test_stream_interface.py b/meshtastic/test/test_stream_interface.py index 2d051cb..57c65d2 100644 --- a/meshtastic/test/test_stream_interface.py +++ b/meshtastic/test/test_stream_interface.py @@ -3,7 +3,7 @@ import pytest -from meshtastic.stream_interface import StreamInterface +from ..stream_interface import StreamInterface @pytest.mark.unit diff --git a/meshtastic/test/test_tcp_interface.py b/meshtastic/test/test_tcp_interface.py index aa35018..432caef 100644 --- a/meshtastic/test/test_tcp_interface.py +++ b/meshtastic/test/test_tcp_interface.py @@ -5,7 +5,7 @@ import re from unittest.mock import patch import pytest -from meshtastic.tcp_interface import TCPInterface +from ..tcp_interface import TCPInterface @pytest.mark.unit From 04534bb90e897b2751d4787a37d6669f39bf9d05 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Thu, 9 Dec 2021 00:44:26 -0800 Subject: [PATCH 3/6] add initial unit test for SerialInterface --- meshtastic/serial_interface.py | 8 ++++---- meshtastic/test/test_serial_interface.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 meshtastic/test/test_serial_interface.py diff --git a/meshtastic/serial_interface.py b/meshtastic/serial_interface.py index 4f8ddf3..90b6922 100644 --- a/meshtastic/serial_interface.py +++ b/meshtastic/serial_interface.py @@ -6,8 +6,8 @@ import os import stat import serial +import meshtastic.util from .stream_interface import StreamInterface -from .util import findPorts, our_exit class SerialInterface(StreamInterface): """Interface class for meshtastic devices over a serial link""" @@ -22,14 +22,14 @@ class SerialInterface(StreamInterface): """ if devPath is None: - ports = findPorts() + ports = meshtastic.util.findPorts() logging.debug(f"ports:{ports}") if len(ports) == 0: - our_exit("Warning: No Meshtastic devices detected.") + meshtastic.util.our_exit("Warning: No Meshtastic devices detected.") elif len(ports) > 1: message = "Warning: Multiple serial ports were detected so one serial port must be specified with the '--port'.\n" message += f" Ports detected:{ports}" - our_exit(message) + meshtastic.util.our_exit(message) else: devPath = ports[0] diff --git a/meshtastic/test/test_serial_interface.py b/meshtastic/test/test_serial_interface.py new file mode 100644 index 0000000..df6f12f --- /dev/null +++ b/meshtastic/test/test_serial_interface.py @@ -0,0 +1,18 @@ +"""Meshtastic unit tests for serial_interface.py""" + +from unittest.mock import patch +import pytest + +from ..serial_interface import SerialInterface + +@pytest.mark.unit +@patch('serial.Serial') +@patch('meshtastic.util.findPorts', return_value=['/dev/ttyUSBfake']) +def test_SerialInterface(mocked_findPorts, mocked_serial): + """Test that we can instantiate a SerialInterface""" + iface = SerialInterface(noProto=True) + iface.showInfo() + iface.localNode.showInfo() + iface.close() + mocked_findPorts.assert_called() + mocked_serial.assert_called() From 7b0fed0987f1799edddfabecdf81897e6631250a Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Thu, 9 Dec 2021 00:56:26 -0800 Subject: [PATCH 4/6] add test with no serial ports detected and with 2 serial ports detected --- meshtastic/test/test_serial_interface.py | 35 ++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/meshtastic/test/test_serial_interface.py b/meshtastic/test/test_serial_interface.py index df6f12f..10b4dbc 100644 --- a/meshtastic/test/test_serial_interface.py +++ b/meshtastic/test/test_serial_interface.py @@ -1,5 +1,8 @@ """Meshtastic unit tests for serial_interface.py""" +import re + + from unittest.mock import patch import pytest @@ -8,11 +11,39 @@ from ..serial_interface import SerialInterface @pytest.mark.unit @patch('serial.Serial') @patch('meshtastic.util.findPorts', return_value=['/dev/ttyUSBfake']) -def test_SerialInterface(mocked_findPorts, mocked_serial): - """Test that we can instantiate a SerialInterface""" +def test_SerialInterface_single_port(mocked_findPorts, mocked_serial): + """Test that we can instantiate a SerialInterface with a single port""" iface = SerialInterface(noProto=True) iface.showInfo() iface.localNode.showInfo() iface.close() mocked_findPorts.assert_called() mocked_serial.assert_called() + + +@pytest.mark.unit +@patch('meshtastic.util.findPorts', return_value=[]) +def test_SerialInterface_no_ports(mocked_findPorts, capsys): + """Test that we can instantiate a SerialInterface with no ports""" + with pytest.raises(SystemExit) as pytest_wrapped_e: + SerialInterface(noProto=True) + mocked_findPorts.assert_called() + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 1 + out, err = capsys.readouterr() + assert re.search(r'Warning: No Meshtastic devices detected', out, re.MULTILINE) + assert err == '' + + +@pytest.mark.unit +@patch('meshtastic.util.findPorts', return_value=['/dev/ttyUSBfake1', '/dev/ttyUSBfake2']) +def test_SerialInterface_multiple_ports(mocked_findPorts, capsys): + """Test that we can instantiate a SerialInterface with two ports""" + with pytest.raises(SystemExit) as pytest_wrapped_e: + SerialInterface(noProto=True) + mocked_findPorts.assert_called() + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 1 + out, err = capsys.readouterr() + assert re.search(r'Warning: Multiple serial ports were detected', out, re.MULTILINE) + assert err == '' From ddd34bfb6a165c3ea4f44bca64f9af1031c6569c Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Thu, 9 Dec 2021 01:08:54 -0800 Subject: [PATCH 5/6] ignore the test dir from code coverage --- .coveragerc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coveragerc b/.coveragerc index 5c70a1a..85bf3bb 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,2 +1,2 @@ [run] -omit = meshtastic/*_pb2.py,meshtastic/test.py +omit = meshtastic/*_pb2.py,meshtastic/test.py,meshtastic/test/*.py From 089d64105e7952bffca9e1c14c8cd3ff5e153fa5 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Thu, 9 Dec 2021 09:14:38 -0800 Subject: [PATCH 6/6] fail build if pylint has issues --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4985df3..3acf7de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,6 @@ jobs: which meshtastic meshtastic --version - name: Run pylint - run: pylint --exit-zero meshtastic + run: pylint meshtastic - name: Run tests with pytest run: pytest --cov=meshtastic