From a248807165dad8b34f494cda236bb88599b134b5 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Mon, 13 Dec 2021 00:00:04 -0800 Subject: [PATCH 1/6] remove print statements that were helpful during dev --- meshtastic/tests/test_main.py | 60 ----------------------------------- 1 file changed, 60 deletions(-) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index bd05a97..651cd7e 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -178,8 +178,6 @@ def test_main_info(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'inside mocked showInfo', out, re.MULTILINE) assert err == '' @@ -197,8 +195,6 @@ def test_main_qr(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) 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 @@ -220,8 +216,6 @@ def test_main_nodes(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'inside mocked showNodes', out, re.MULTILINE) assert err == '' @@ -238,8 +232,6 @@ def test_main_set_owner_to_bob(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Setting device owner to bob', out, re.MULTILINE) assert err == '' @@ -266,8 +258,6 @@ def test_main_set_ham_to_KI123(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) 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) @@ -293,8 +283,6 @@ def test_main_reboot(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'inside mocked reboot', out, re.MULTILINE) assert err == '' @@ -315,8 +303,6 @@ def test_main_sendtext(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) 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) @@ -338,8 +324,6 @@ def test_main_sendping(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Sending ping message', out, re.MULTILINE) assert re.search(r'inside mocked sendData', out, re.MULTILINE) @@ -367,8 +351,6 @@ def test_main_setlat(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) 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) @@ -398,8 +380,6 @@ def test_main_setlon(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) 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) @@ -429,8 +409,6 @@ def test_main_setalt(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) 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) @@ -460,8 +438,6 @@ def test_main_set_team_valid(capsys, reset_globals): mm.Value.return_value = 'FAKEVAL' main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Setting team to', out, re.MULTILINE) assert err == '' @@ -486,8 +462,6 @@ def test_main_set_team_invalid(capsys, reset_globals): mm.Value.side_effect = throw_an_exception main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'ERROR: Team', out, re.MULTILINE) assert err == '' @@ -505,8 +479,6 @@ def test_main_seturl(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert err == '' mo.assert_called() @@ -531,8 +503,6 @@ def test_main_set_valid(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Set wifi_ssid to foo', out, re.MULTILINE) assert err == '' @@ -557,8 +527,6 @@ def test_main_set_with_invalid(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'does not have an attribute called foo', out, re.MULTILINE) assert err == '' @@ -584,8 +552,6 @@ def test_main_configure(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Setting device owner', out, re.MULTILINE) assert re.search(r'Setting channel url', out, re.MULTILINE) @@ -618,8 +584,6 @@ def test_main_ch_add_valid(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Writing modified channels to device', out, re.MULTILINE) assert err == '' @@ -650,8 +614,6 @@ def test_main_ch_add_invalid_name_too_long(capsys, reset_globals): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - print('out:', out) - print('err:', err) 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 == '' @@ -677,8 +639,6 @@ def test_main_ch_add_but_name_already_exists(capsys, reset_globals): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Warning: This node already has', out, re.MULTILINE) assert err == '' @@ -706,8 +666,6 @@ def test_main_ch_add_but_no_more_channels(capsys, reset_globals): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - print('out:', out) - print('err:', err) 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 == '' @@ -728,8 +686,6 @@ def test_main_ch_del(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Deleting channel', out, re.MULTILINE) assert err == '' @@ -753,8 +709,6 @@ def test_main_ch_del_no_ch_index_specified(capsys, reset_globals): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Warning: Need to specify', out, re.MULTILINE) assert err == '' @@ -779,8 +733,6 @@ def test_main_ch_del_primary_channel(capsys, reset_globals): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Warning: Cannot delete primary channel', out, re.MULTILINE) assert err == '' @@ -801,8 +753,6 @@ def test_main_ch_enable_valid_secondary_channel(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Writing modified channels', out, re.MULTILINE) assert err == '' @@ -824,8 +774,6 @@ def test_main_ch_disable_valid_secondary_channel(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Writing modified channels', out, re.MULTILINE) assert err == '' @@ -850,8 +798,6 @@ def test_main_ch_enable_without_a_ch_index(capsys, reset_globals): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Warning: Need to specify', out, re.MULTILINE) assert err == '' @@ -876,8 +822,6 @@ def test_main_ch_enable_primary_channel(capsys, reset_globals): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Warning: Cannot enable/disable PRIMARY', out, re.MULTILINE) assert err == '' @@ -902,8 +846,6 @@ def test_main_ch_range_options(capsys, reset_globals): with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo: main() out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Writing modified channels', out, re.MULTILINE) assert err == '' @@ -927,8 +869,6 @@ def test_main_ch_longsfast_on_non_primary_channel(capsys, reset_globals): assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 out, err = capsys.readouterr() - print('out:', out) - print('err:', err) assert re.search(r'Connected to radio', out, re.MULTILINE) assert re.search(r'Warning: Standard channel settings', out, re.MULTILINE) assert err == '' From 8927fdcd1e3f740a0ad4762ba1670bf8cbb6b04e Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Wed, 15 Dec 2021 12:54:59 -0800 Subject: [PATCH 2/6] figured out how to test --pos-fields --- meshtastic/tests/test_main.py | 56 ++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 651cd7e..fe72806 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -7,7 +7,7 @@ from unittest.mock import patch, MagicMock import pytest from meshtastic.__main__ import initParser, main, Globals - +import meshtastic.radioconfig_pb2 from ..serial_interface import SerialInterface from ..node import Node from ..radioconfig_pb2 import RadioConfig @@ -533,6 +533,7 @@ def test_main_set_with_invalid(capsys, reset_globals): mo.assert_called() +# TODO: write some negative --configure tests @pytest.mark.unit def test_main_configure(capsys, reset_globals): """Test --configure with valid file""" @@ -873,3 +874,56 @@ def test_main_ch_longsfast_on_non_primary_channel(capsys, reset_globals): assert re.search(r'Warning: Standard channel settings', out, re.MULTILINE) assert err == '' mo.assert_called() + + +# TODO: pos_fields: no args +# TODO: pos_fields: invalid arg of '0' to show list +# TODO: pos_fields: set valid number (35) +# TODO: pos_fields: set invalid number (3000?) + +# 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 + +@pytest.mark.unit +def test_main_pos_fields_no_args(capsys, reset_globals): + """Test --pos-fields no args (which shows settings)""" + sys.argv = ['', '--pos-fields'] + Globals.getInstance().set_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: + # kind of cheating here, we are setting up the node + mocked_node = MagicMock(autospec=Node) + anode = mocked_node() + anode.radioConfig.preferences.position_flags = 35 + Globals.getInstance().set_target_node(anode) + + 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 == '' From d44e06420afb35ae89bf2cbadf9d44efdef68393 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Wed, 15 Dec 2021 13:41:28 -0800 Subject: [PATCH 3/6] add couple more tests for --pos-fields --- meshtastic/tests/test_main.py | 64 ++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index fe72806..ac37011 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -876,11 +876,6 @@ def test_main_ch_longsfast_on_non_primary_channel(capsys, reset_globals): mo.assert_called() -# TODO: pos_fields: no args -# TODO: pos_fields: invalid arg of '0' to show list -# TODO: pos_fields: set valid number (35) -# TODO: pos_fields: set invalid number (3000?) - # 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: @@ -927,3 +922,62 @@ def test_main_pos_fields_no_args(capsys, reset_globals): 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 == '' + + +@pytest.mark.unit +def test_main_pos_fields_arg_of_zero(capsys, reset_globals): + """Test --pos-fields an arg of 0 (which shows list)""" + sys.argv = ['', '--pos-fields', '0'] + Globals.getInstance().set_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 == '' + + +@pytest.mark.unit +def test_main_pos_fields_valid_values(capsys, reset_globals): + """Test --pos-fields with valid values""" + sys.argv = ['', '--pos-fields', 'POS_GEO_SEP', 'POS_ALT_MSL'] + Globals.getInstance().set_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 == '' From dae1f08632ecae72d50782b01a25907d7f089985 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Wed, 15 Dec 2021 13:46:36 -0800 Subject: [PATCH 4/6] remove lines that are not needed --- meshtastic/tests/test_main.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index ac37011..47f91b5 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -10,7 +10,6 @@ from meshtastic.__main__ import initParser, main, Globals import meshtastic.radioconfig_pb2 from ..serial_interface import SerialInterface from ..node import Node -from ..radioconfig_pb2 import RadioConfig from ..channel_pb2 import Channel @@ -490,12 +489,7 @@ def test_main_set_valid(capsys, reset_globals): sys.argv = ['', '--set', 'wifi_ssid', 'foo'] Globals.getInstance().set_args(sys.argv) - mocked_user_prefs = MagicMock(autospec=RadioConfig.UserPreferences) - mocked_user_prefs.phone_timeout_secs.return_value = 900 - mocked_user_prefs.ls_secs.return_value = 300 - mocked_node = MagicMock(autospec=Node) - mocked_node.radioConfig.preferences = ( mocked_user_prefs ) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node @@ -540,12 +534,7 @@ def test_main_configure(capsys, reset_globals): sys.argv = ['', '--configure', 'example_config.yaml'] Globals.getInstance().set_args(sys.argv) - mocked_user_prefs = MagicMock(autospec=RadioConfig.UserPreferences) - mocked_user_prefs.phone_timeout_secs.return_value = 900 - mocked_user_prefs.ls_secs.return_value = 300 - mocked_node = MagicMock(autospec=Node) - mocked_node.radioConfig.preferences = ( mocked_user_prefs ) iface = MagicMock(autospec=SerialInterface) iface.getNode.return_value = mocked_node From 5e1e968ccd24e2274b39975c3e13bcbb62999658 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Wed, 15 Dec 2021 14:21:37 -0800 Subject: [PATCH 5/6] add main unit test for --get --- meshtastic/tests/test_main.py | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 47f91b5..2d14b0b 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -970,3 +970,56 @@ def test_main_pos_fields_valid_values(capsys, reset_globals): 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 == '' + + +@pytest.mark.unit +def test_main_get_with_valid_values(capsys, reset_globals): + """Test --get with valid values (with string, number, boolean)""" + sys.argv = ['', '--get', 'ls_secs', '--get', 'wifi_ssid', '--get', 'fixed_position'] + Globals.getInstance().set_args(sys.argv) + + with patch('meshtastic.serial_interface.SerialInterface') as mo: + + # kind of cheating here, we are setting up the node + mocked_node = MagicMock(autospec=Node) + anode = mocked_node() + anode.radioConfig.preferences.wifi_ssid = 'foo' + anode.radioConfig.preferences.ls_secs = 300 + anode.radioConfig.preferences.fixed_position = False + Globals.getInstance().set_target_node(anode) + + 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 == '' + + +@pytest.mark.unit +def test_main_get_with_invalid(capsys, reset_globals): + """Test --get with invalid field""" + sys.argv = ['', '--get', 'foo'] + Globals.getInstance().set_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.radioConfig.preferences = ( 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'does not have an attribute called foo', out, re.MULTILINE) + assert re.search(r'Choices in sorted order are', out, re.MULTILINE) + assert err == '' + mo.assert_called() From 712f1f5288da42e6d01b682baee31913a06c8b84 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Wed, 15 Dec 2021 14:44:28 -0800 Subject: [PATCH 6/6] add main unit test --noproto, --seriallog, and a deprecated arg --- meshtastic/tests/test_main.py | 83 +++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 2d14b0b..ba7d918 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -1,6 +1,7 @@ """Meshtastic unit tests for __main__.py""" import sys +import os import re from unittest.mock import patch, MagicMock @@ -183,6 +184,73 @@ def test_main_info(capsys, reset_globals): mo.assert_called() +@pytest.mark.unit +def test_main_no_proto(capsys, reset_globals): + """Test --noproto (using --info for output)""" + sys.argv = ['', '--info', '--noproto'] + Globals.getInstance().set_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): + 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 +def test_main_info_with_seriallog_stdout(capsys, reset_globals): + """Test --info""" + sys.argv = ['', '--info', '--seriallog', 'stdout'] + Globals.getInstance().set_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 +def test_main_info_with_seriallog_output_txt(capsys, reset_globals): + """Test --info""" + sys.argv = ['', '--info', '--seriallog', 'output.txt'] + Globals.getInstance().set_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 def test_main_qr(capsys, reset_globals): """Test --qr""" @@ -1023,3 +1091,18 @@ def test_main_get_with_invalid(capsys, reset_globals): assert re.search(r'Choices in sorted order are', out, re.MULTILINE) assert err == '' mo.assert_called() + + +@pytest.mark.unit +def test_main_setchan(capsys, reset_globals): + """Test --setchan (deprecated)""" + sys.argv = ['', '--setchan', 'a', 'b'] + Globals.getInstance().set_args(sys.argv) + + iface = MagicMock(autospec=SerialInterface) + + 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