mirror of
https://github.com/esphome/esphome.git
synced 2026-09-19 02:58:38 +00:00
nRF52 has its own upload_program that runs before the default dispatch
in esphome.__main__. The mcumgr/BLE OTA path reads the MCUboot-signed
update image from CORE.relative_pioenvs_path(name, 'zephyr',
'app_update.bin'), which assumes a local Zephyr build tree.
Consult CORE.prebuilt_artifact_path('app_update.bin') first so the
dashboard's transparent BLE install on a Bluetooth proxy can flash a
prebuilt update image without compiling locally.
Serial uploads on non-MCUboot bootloaders still go through
adafruit-nrfutil via _upload_using_platformio and are out of scope here;
they need their own bypass to work with --prebuilt-dir (tracked
separately).
Issue: esphome/device-builder#572
53 lines
1.8 KiB
Python
53 lines
1.8 KiB
Python
"""Tests for the nrf52 component's custom upload_program."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
from esphome.core import CORE
|
|
|
|
|
|
def test_nrf52_upload_program_prebuilt_dir_for_ble_ota(tmp_path: Path) -> None:
|
|
"""`esphome upload --prebuilt-dir <path>` for an nRF52 Bluetooth proxy
|
|
ships the MCUboot-signed update at <prebuilt-dir>/app_update.bin so the
|
|
dashboard's transparent BLE install doesn't need a local Zephyr build
|
|
tree. Verify the nrf52 upload_program picks up that path instead of
|
|
`CORE.relative_pioenvs_path(..., "zephyr", "app_update.bin")`.
|
|
"""
|
|
prebuilt = tmp_path / "prebuilt"
|
|
prebuilt.mkdir()
|
|
expected_firmware = prebuilt / "app_update.bin"
|
|
expected_firmware.write_bytes(b"signed-mcuboot-image")
|
|
CORE.prebuilt_dir = prebuilt
|
|
CORE.name = "bt-proxy"
|
|
|
|
captured_firmware: list[Path] = []
|
|
|
|
async def fake_upload(device: str, firmware: Path) -> None:
|
|
captured_firmware.append(firmware)
|
|
|
|
# Patch the heavy nrf52 surface so we exercise only the firmware-path
|
|
# resolution: BLE scan returns a fake device, smpmgr_upload records the
|
|
# firmware path it would have flashed.
|
|
with (
|
|
patch(
|
|
"esphome.components.nrf52.ota.smpmgr_scan",
|
|
new=AsyncMock(return_value="AA:BB:CC:DD:EE:FF"),
|
|
),
|
|
patch(
|
|
"esphome.components.nrf52.ota.smpmgr_upload",
|
|
new=fake_upload,
|
|
),
|
|
patch(
|
|
"esphome.components.nrf52.ble_logger.is_mac_address",
|
|
return_value=False,
|
|
),
|
|
):
|
|
from esphome.components.nrf52 import upload_program
|
|
|
|
handled = upload_program({}, MagicMock(), "BLE")
|
|
|
|
assert handled is True
|
|
assert captured_firmware == [expected_firmware.resolve()]
|