92 lines
4.3 KiB
Python
92 lines
4.3 KiB
Python
"""arduino-cli failures reach the UI / agent as one actionable sentence.
|
|
|
|
Regression for 2026-08-17: a fresh desktop install has no library index
|
|
yet; when arduino-cli could not download it (firewall / proxy) `lib search`
|
|
returned a JSON blob on stderr and we forwarded it verbatim, so the in-app
|
|
agent told the user "the library server returns a JSON error" ten times in
|
|
a row. The strings below are the real arduino-cli 1.0.4 output captured
|
|
offline (`unshare -n`) against an empty data dir.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
_REPO = Path(__file__).resolve().parents[3]
|
|
sys.path.insert(0, str(_REPO / "backend"))
|
|
|
|
from app.services.arduino_cli import humanize_cli_error # noqa: E402
|
|
|
|
SEARCH_JSON_STDERR = (
|
|
'{\n "error": "Error updating library index: Error downloading index '
|
|
"'https://downloads.arduino.cc/libraries/library_index.tar.bz2': Get "
|
|
'\\"https://downloads.arduino.cc/libraries/library_index.tar.bz2\\": dial tcp: '
|
|
'lookup downloads.arduino.cc on 127.0.0.53:53: dial udp 127.0.0.53:53: connect: '
|
|
'network is unreachable",\n "warnings": [\n "Error initializing instance: '
|
|
"Error downloading index 'https://downloads.arduino.cc/libraries/library_index.tar.bz2'\"\n ]\n}"
|
|
)
|
|
|
|
INSTALL_NO_INDEX_STDERR = (
|
|
"Error initializing instance: Error downloading index "
|
|
"'https://downloads.arduino.cc/libraries/library_index.tar.bz2': Get "
|
|
'"https://downloads.arduino.cc/libraries/library_index.tar.bz2": dial tcp: lookup '
|
|
"downloads.arduino.cc on 127.0.0.53:53: dial udp 127.0.0.53:53: connect: network is unreachable\n"
|
|
"Error initializing instance: Loading index file: reading library_index.json: open "
|
|
"/x/data/library_index.json: no such file or directory\n"
|
|
)
|
|
|
|
INSTALL_NO_NET_WITH_INDEX = (
|
|
"Downloading Adafruit GFX Library@1.12.6...\n"
|
|
'Adafruit GFX Library@1.12.6 Get "https://downloads.arduino.cc/libraries/github.com/adafruit/'
|
|
'Adafruit_GFX_Library-1.12.6.zip?query=install": dial tcp: lookup downloads.arduino.cc on '
|
|
"127.0.0.53:53: dial udp 127.0.0.53:53: connect: network is unreachable\n"
|
|
"Error installing Adafruit GFX Library: Can't download library: Get "
|
|
'"https://downloads.arduino.cc/libraries/github.com/adafruit/Adafruit_GFX_Library-1.12.6.zip'
|
|
'?query=install": dial tcp: lookup downloads.arduino.cc on 127.0.0.53:53: dial udp '
|
|
"127.0.0.53:53: connect: network is unreachable\n"
|
|
)
|
|
|
|
|
|
def test_search_json_error_becomes_index_download_sentence():
|
|
msg = humanize_cli_error(SEARCH_JSON_STDERR, action="search libraries")
|
|
assert msg.startswith("Could not search libraries:")
|
|
assert "library index" in msg
|
|
assert "downloads.arduino.cc" in msg
|
|
assert "firewall or proxy" in msg
|
|
# No JSON leaks through to the user / agent.
|
|
assert "{" not in msg and "warnings" not in msg
|
|
|
|
|
|
def test_install_without_index_is_the_same_story():
|
|
msg = humanize_cli_error(INSTALL_NO_INDEX_STDERR, action="install Adafruit GFX Library")
|
|
assert msg.startswith("Could not install Adafruit GFX Library:")
|
|
assert "library index" in msg
|
|
assert "downloads.arduino.cc" in msg
|
|
|
|
|
|
def test_install_with_index_but_no_network_names_the_download():
|
|
msg = humanize_cli_error(INSTALL_NO_NET_WITH_INDEX, action="install Adafruit GFX Library")
|
|
assert msg.startswith("Could not install Adafruit GFX Library:")
|
|
assert "download from downloads.arduino.cc failed" in msg
|
|
assert "firewall or proxy" in msg
|
|
|
|
|
|
def test_unknown_library_passes_the_cli_line_through():
|
|
msg = humanize_cli_error("Error installing NoSuchLib: Library 'NoSuchLib' not found", action="install NoSuchLib")
|
|
assert msg == "Could not install NoSuchLib: Error installing NoSuchLib: Library 'NoSuchLib' not found"
|
|
|
|
|
|
def test_empty_and_unknown_shapes_still_return_a_sentence():
|
|
assert humanize_cli_error("", action="search libraries") == (
|
|
"Could not search libraries: arduino-cli returned no output."
|
|
)
|
|
assert humanize_cli_error(None, action="search libraries").startswith("Could not search libraries:")
|
|
long = "x" * 1000
|
|
msg = humanize_cli_error(long, action="search libraries")
|
|
assert msg.startswith("Could not search libraries: ") and len(msg) < 400
|
|
|
|
|
|
def test_multiline_unknown_error_uses_first_line_only():
|
|
msg = humanize_cli_error("\n\nfirst line here\nsecond line\n", action="search libraries")
|
|
assert msg == "Could not search libraries: first line here"
|