Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion meshtastic/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1093,14 +1093,15 @@ def setSimpleConfig(modem_preset):
"Use the '--get' command for a specific configuration (e.g. 'lora') instead."
)

completed_get = False
if args.get:
closeNow = True
node = interface.getNode(args.dest, False, **getNode_kwargs)
for pref in args.get:
found = getPref(node, pref[0])

if found:
print("Completed getting preferences")
completed_get = True

if args.nodes:
closeNow = True
Expand Down Expand Up @@ -1194,13 +1195,18 @@ def setSimpleConfig(modem_preset):
time.sleep(int(args.wait_to_disconnect))

# if the user didn't ask for serial debugging output, we might want to exit after we've done our operation
did_close_interface = False
if (not args.seriallog) and closeNow:
interface.close() # after running command then exit
did_close_interface = True

# Close any structured logs after we've done all of our API operations
if log_set:
log_set.close()

if completed_get and did_close_interface:
print("Completed getting preferences")

except Exception as ex:
print(f"Aborting due to: {ex}")
interface.close() # close the connection now, so that our app exits
Comment thread
the8thbit marked this conversation as resolved.
Expand Down
45 changes: 45 additions & 0 deletions meshtastic/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,51 @@ def test_main_ch_longfast_on_non_primary_channel(capsys):
# assert err == ""


@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_get_reports_completion_after_closing():
"""A one-shot get must finish shutting down before reporting success."""
sys.argv = ["", "--get", "lora"]
mt_config.args = sys.argv

events = []
iface = MagicMock(autospec=SerialInterface)
iface.close.side_effect = lambda: events.append("close")

def record_print(*values, **_kwargs):
events.append(" ".join(str(value) for value in values))

with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
with patch("meshtastic.__main__.getPref", return_value=True):
with patch("builtins.print", side_effect=record_print):
main()

assert events.count("Completed getting preferences") == 1
assert events.index("close") < events.index("Completed getting preferences")


@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@pytest.mark.parametrize("keep_open_args", [["--listen"], ["--seriallog", "stdout"]])
def test_main_get_does_not_report_completion_while_connection_stays_open(
capsys, keep_open_args
):
"""A get must not report post-cleanup success when cleanup is skipped."""
sys.argv = ["", "--get", "lora", *keep_open_args]
mt_config.args = sys.argv

iface = MagicMock(autospec=SerialInterface)

with patch("meshtastic.serial_interface.SerialInterface", return_value=iface):
with patch("meshtastic.__main__.getPref", return_value=True):
with patch("meshtastic.__main__.time.sleep", side_effect=KeyboardInterrupt):
main()

out, _err = capsys.readouterr()
iface.close.assert_not_called()
assert "Completed getting preferences" not in out


@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_get_with_invalid(capsys):
Expand Down