Skip to content
Merged
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
9 changes: 7 additions & 2 deletions cli/src/mpftp/sidecar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,10 @@ def _network_open_error(self, device: str, exc: BaseException) -> str:
answers ping (lwIP has its own task), but WebREPL never replies, since
the esp32 port only services its sockets from the VM's poll hook. So a
silent WebREPL on a host that answers ping, or on a board that logged
in earlier in this session, is a busy board, and the user is told so.
in earlier, is a busy board, and the user is told so. When the TCP
connect itself timed out, though, the board may simply be off: then
ping decides even for a board that answered before, so a switched-off
board isn't sent to serial or the reset button.
"""
text = str(exc)
if isinstance(exc, webrepl.WebReplAuthError):
Expand All @@ -1172,7 +1175,9 @@ def _network_open_error(self, device: str, exc: BaseException) -> str:
)
if not silent:
return text
if "never answered the WebSocket upgrade" in text or device in self._answered:
if "never answered the WebSocket upgrade" in text:
return f"{device}: {wifiboard.STUCK_MESSAGE}"
if device in self._answered and "no answer from" not in text:
return f"{device}: {wifiboard.STUCK_MESSAGE}"
try:
host = webrepl.parse_device(device)[0]
Expand Down
21 changes: 19 additions & 2 deletions cli/tests/test_wifi_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,14 +375,31 @@ def test_a_host_that_is_gone_keeps_the_plain_message(self):
with mock.patch.object(webrepl, "host_answers_ping", return_value=False):
self.assertEqual(s._network_open_error("ws://10.0.0.5", err), str(err))

def test_a_board_that_answered_before_is_busy_without_asking_ping(self):
def test_a_board_that_answered_before_and_goes_quiet_after_connecting_is_busy(self):
s = sidecar.Session()
s._answered.add("ws://10.0.0.5")
err = webrepl.WebReplError("ws://10.0.0.5: no answer from 10.0.0.5:8266 in 5 s.")
err = webrepl.WebReplError("ws://10.0.0.5: no the password prompt within 5 s (got b'')")
with mock.patch.object(webrepl, "host_answers_ping") as ping:
self.assertIn(wifiboard.STUCK_MESSAGE, s._network_open_error("ws://10.0.0.5", err))
ping.assert_not_called()

def test_a_board_that_answered_before_and_is_now_off_is_not_called_busy(self):
# A saved board that's switched off: the TCP connect times out and
# ping gets no answer, so the plain "is the board on this network"
# message stands.
s = sidecar.Session()
s._answered.add("ws://10.0.0.5")
err = webrepl.WebReplError("ws://10.0.0.5: no answer from 10.0.0.5:8266 in 5 s.")
with mock.patch.object(webrepl, "host_answers_ping", return_value=False):
self.assertEqual(s._network_open_error("ws://10.0.0.5", err), str(err))

def test_a_board_that_answered_before_and_still_answers_ping_is_busy(self):
s = sidecar.Session()
s._answered.add("ws://10.0.0.5")
err = webrepl.WebReplError("ws://10.0.0.5: no answer from 10.0.0.5:8266 in 5 s.")
with mock.patch.object(webrepl, "host_answers_ping", return_value=True):
self.assertIn(wifiboard.STUCK_MESSAGE, s._network_open_error("ws://10.0.0.5", err))

def test_a_refused_connection_is_not_called_busy(self):
s = sidecar.Session()
s._answered.add("ws://10.0.0.5")
Expand Down
Loading