From 96a5f316ea285bb95cef9130d56e79f9250f57a8 Mon Sep 17 00:00:00 2001 From: Mike Kinney Date: Thu, 9 Dec 2021 13:41:24 -0800 Subject: [PATCH] refactor two more globals into Globals: channel_index and target_node --- meshtastic/__main__.py | 12 +++--- meshtastic/globals.py | 21 ++++++++- meshtastic/remote_hardware.py | 3 +- meshtastic/test/test_main.py | 81 ++++++++++++++++++++++++++++++++++- 4 files changed, 106 insertions(+), 11 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 24217bb..cc8c484 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -23,8 +23,6 @@ from .globals import Globals """We only import the tunnel code if we are on a platform that can run it""" have_tunnel = platform.system() == 'Linux' -channelIndex = 0 - def onReceive(packet, interface): """Callback invoked when a packet arrives""" @@ -131,9 +129,6 @@ def setPref(attributes, name, valStr): print(f"Can't set {name} due to {ex}") -targetNode = None - - def onConnected(interface): """Callback invoked when we connect to a radio""" closeNow = False # Should we drop the connection after we finish? @@ -145,9 +140,10 @@ def onConnected(interface): def getNode(): """This operation could be expensive, so we try to cache the results""" - global targetNode + targetNode = our_globals.get_target_node() if not targetNode: targetNode = interface.getNode(args.destOrLocal) + our_globals.set_target_node(targetNode) return targetNode if args.setlat or args.setlon or args.setalt: @@ -374,12 +370,14 @@ def onConnected(interface): if args.ch_del: closeNow = True + channelIndex = our_globals.get_channel_index() print(f"Deleting channel {channelIndex}") ch = getNode().deleteChannel(channelIndex) if args.ch_set or args.ch_longslow or args.ch_longfast or args.ch_mediumslow or args.ch_mediumfast or args.ch_shortslow or args.ch_shortfast: closeNow = True + channelIndex = our_globals.get_channel_index() ch = getNode().channels[channelIndex] enable = args.ch_enable # should we enable this channel? @@ -521,8 +519,8 @@ def common(): sys.exit(0) if args.ch_index is not None: - global channelIndex channelIndex = int(args.ch_index) + our_globals.set_channel_index(channelIndex) # Some commands require dest to be set, so we now use destOrAll/destOrLocal for more lenient commands if not args.dest: diff --git a/meshtastic/globals.py b/meshtastic/globals.py index c255e81..eec25f5 100644 --- a/meshtastic/globals.py +++ b/meshtastic/globals.py @@ -4,7 +4,8 @@ This is not much better than using python's globals, but it allows us to better test meshtastic. Plus, there are some weird python global issues/gotcha that we can hopefully avoid by using this - class in stead. + class instead. + """ class Globals: @@ -26,6 +27,8 @@ class Globals: Globals.__instance = self self.args = None self.parser = None + self.target_node = None + self.channel_index = 0 def set_args(self, args): """Set the args""" @@ -35,6 +38,14 @@ class Globals: """Set the parser""" self.parser = parser + def set_target_node(self, target_node): + """Set the target_node""" + self.target_node = target_node + + def set_channel_index(self, channel_index): + """Set the channel_index""" + self.channel_index = channel_index + def get_args(self): """Get args""" return self.args @@ -42,3 +53,11 @@ class Globals: def get_parser(self): """Get parser""" return self.parser + + def get_target_node(self): + """Get target_node""" + return self.target_node + + def get_channel_index(self): + """Get channel_index""" + return self.channel_index diff --git a/meshtastic/remote_hardware.py b/meshtastic/remote_hardware.py index 2e0dac9..5fa9f76 100644 --- a/meshtastic/remote_hardware.py +++ b/meshtastic/remote_hardware.py @@ -38,9 +38,8 @@ class RemoteHardwareClient: def _sendHardware(self, nodeid, r, wantResponse=False, onResponse=None): if not nodeid: - # pylint: disable=W1401 raise Exception( - "You must set a destination node ID for this operation (use --dest \!xxxxxxxxx)") + r"You must set a destination node ID for this operation (use --dest \!xxxxxxxxx)") return self.iface.sendData(r, nodeid, portnums_pb2.REMOTE_HARDWARE_APP, wantAck=True, channelIndex=self.channelIndex, wantResponse=wantResponse, onResponse=onResponse) diff --git a/meshtastic/test/test_main.py b/meshtastic/test/test_main.py index c745d5a..d9eaaaa 100644 --- a/meshtastic/test/test_main.py +++ b/meshtastic/test/test_main.py @@ -6,7 +6,7 @@ import re import pytest -from meshtastic.__main__ import initParser, Globals +from meshtastic.__main__ import initParser, main, Globals @pytest.mark.unit @@ -41,3 +41,82 @@ def test_main_init_parser_version(capsys): out, err = capsys.readouterr() assert re.match(r'[0-9]+\.[0-9]+\.[0-9]', out) assert err == '' + + +@pytest.mark.unit +def test_main_main_version(capsys): + """Test --version""" + sys.argv = ['', '--version'] + args = sys.argv + parser = None + parser = argparse.ArgumentParser() + our_globals = Globals.getInstance() + our_globals.set_parser(parser) + our_globals.set_args(args) + 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]+\.[0-9]', out) + assert err == '' + + +@pytest.mark.unit +def test_main_main_no_args(): + """Test with no args""" + sys.argv = [''] + args = sys.argv + parser = None + parser = argparse.ArgumentParser() + our_globals = Globals.getInstance() + our_globals.set_parser(parser) + our_globals.set_args(args) + with pytest.raises(SystemExit) as pytest_wrapped_e: + main() + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 1 + + +@pytest.mark.unit +def test_main_support(capsys): + """Test --support""" + sys.argv = ['', '--support'] + args = sys.argv + parser = None + parser = argparse.ArgumentParser() + our_globals = Globals.getInstance() + our_globals.set_parser(parser) + our_globals.set_args(args) + 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 +def test_main_ch_index_no_devices(capsys): + """Test --ch-index 1""" + sys.argv = ['', '--ch-index', '1'] + args = sys.argv + parser = None + parser = argparse.ArgumentParser() + our_globals = Globals.getInstance() + our_globals.set_parser(parser) + our_globals.set_args(args) + assert our_globals.get_target_node() is None + assert our_globals.get_channel_index() == 0 + with pytest.raises(SystemExit) as pytest_wrapped_e: + main() + assert our_globals.get_channel_index() == 1 + 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 == ''