Harden the summary against foreign json shapes and partition edge cases

This commit is contained in:
J. Nick Koston
2026-08-28 11:44:48 -05:00
parent b66990fbff
commit c75e3898e4
2 changed files with 55 additions and 2 deletions
+9 -2
View File
@@ -119,10 +119,14 @@ def print_summary(size_json: Path, partitions_csv: Path, firmware_elf: Path) ->
except (OSError, json.JSONDecodeError) as e:
_LOGGER.debug("Skipping size summary: %s", e)
return
if not isinstance(data, dict):
_LOGGER.warning("Skipping size summary: unexpected json shape in %s", size_json)
return
layout = data.get("layout")
regions = {
entry.get("name"): entry
for entry in data.get("layout", [])
for entry in (layout if isinstance(layout, list) else [])
if isinstance(entry, dict)
}
# Every chip has a DRAM or DIRAM region, so a warning here usually
@@ -154,7 +158,10 @@ def print_summary(size_json: Path, partitions_csv: Path, firmware_elf: Path) ->
return
try:
app_size = _find_app_partition_size(partitions_csv)
except ValueError as e:
except (OSError, ValueError) as e:
_LOGGER.debug("Skipping Flash summary: %s", e)
return
if app_size <= 0:
_LOGGER.debug("Skipping Flash summary: app partition size is 0")
return
print_size_line("Flash", flash_used, app_size)
+46
View File
@@ -211,6 +211,52 @@ def test_print_summary_flash_line_derives_from_elf(
assert "(used 724215 bytes from 1835008 bytes)" in out
@pytest.mark.parametrize(
"data",
[
pytest.param([1, 2], id="top_level_list"),
pytest.param({"version": "1.1", "layout": None}, id="layout_null"),
pytest.param({"version": "1.1", "layout": 7}, id="layout_scalar"),
],
)
def test_print_summary_handles_unexpected_shapes(
data: object, tmp_path: Path, capsys: pytest.CaptureFixture[str]
) -> None:
"""A foreign-schema size json degrades to a warning, never a traceback."""
size_json = _write_size_json(tmp_path, data)
_print_summary_ram_only(tmp_path, size_json)
assert capsys.readouterr().out == ""
def test_print_summary_skips_flash_on_zero_app_partition(
tmp_path: Path, capsys: pytest.CaptureFixture[str]
) -> None:
"""A zero-size app partition skips the Flash line rather than printing
a from-0-bytes figure CI would record."""
size_json = _write_size_json(tmp_path, _esp32_size_data())
partitions = tmp_path / "partitions.csv"
partitions.write_text(
"# name, type, subtype, offset, size, flags\napp0, app, ota_0, 0x10000, 0x0,\n"
)
print_summary(size_json, partitions, tmp_path / "firmware.elf")
out = capsys.readouterr().out
assert "Flash:" not in out
def test_print_summary_skips_flash_on_unreadable_partitions(
tmp_path: Path, capsys: pytest.CaptureFixture[str]
) -> None:
"""An unreadable partitions.csv is non-fatal."""
size_json = _write_size_json(tmp_path, _esp32_size_data())
partitions = _write_partitions(tmp_path)
partitions.chmod(0o000)
try:
print_summary(size_json, partitions, tmp_path / "firmware.elf")
finally:
partitions.chmod(0o644)
assert "Flash:" not in capsys.readouterr().out
def test_print_summary_flash_falls_back_on_bad_total_size(
tmp_path: Path, capsys: pytest.CaptureFixture[str]
) -> None: