mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[api] Cover the PlatformIO toolchain in the managed component tests
The ESP-IDF framework can also be built with the PlatformIO toolchain, and the managed components are used on both. Record why that choice is deliberately toolchain-independent: wireguard splits on the same condition, and if the two ever disagree one of them converts a second libsodium next to the managed one. The test now sets the toolchain explicitly and asserts the PlatformIO one takes the managed path too, so the condition cannot narrow without a test failing.
This commit is contained in:
@@ -502,12 +502,17 @@ async def to_code(config: ConfigType) -> None:
|
||||
# and plaintext disabled. Only a factory reset can remove it.
|
||||
cg.add_define("USE_API_PLAINTEXT")
|
||||
cg.add_define("USE_API_NOISE")
|
||||
# Both libraries build themselves as ESP-IDF components, so on ESP-IDF
|
||||
# Both libraries build themselves as ESP-IDF components, so on ESP32
|
||||
# they are pulled straight from the component registry instead of going
|
||||
# through ESPHome's PlatformIO-library converter. Not on the Arduino
|
||||
# framework: arduino-esp32 brings its own espressif/libsodium (on IDF
|
||||
# < 6.0), and IDF refuses to build with two managed components whose
|
||||
# names differ only by namespace.
|
||||
# through ESPHome's PlatformIO-library converter. Deliberately not
|
||||
# conditional on the toolchain: wireguard splits on the same condition,
|
||||
# and if the two disagree one of them converts a second libsodium next
|
||||
# to the managed one.
|
||||
#
|
||||
# Not on the Arduino framework though: arduino-esp32 depends on
|
||||
# espressif/libsodium of its own (on IDF < 6.0), so the component
|
||||
# manager would see two managed components whose names match once the
|
||||
# namespace is stripped, and refuse to pick between them.
|
||||
if CORE.is_esp32 and not CORE.using_arduino:
|
||||
from esphome.components.esp32 import add_idf_component
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
"""Tests for the noise-c/libsodium library wiring in api's to_code.
|
||||
|
||||
On ESP-IDF (not Arduino) both libraries build themselves as native ESP-IDF
|
||||
managed components, so they are declared via add_idf_component() instead of
|
||||
going through ESPHome's PlatformIO-library converter. On every other target
|
||||
(and on the Arduino framework, where arduino-esp32 brings its own bundled
|
||||
espressif/libsodium) noise-c still goes through the PlatformIO-library
|
||||
converter via cg.add_library(). This drives the real to_code() coroutine so
|
||||
both branches of that decision are exercised end to end, not just mocked.
|
||||
On ESP32 (but not the Arduino framework) both libraries build themselves as
|
||||
native ESP-IDF managed components, so they are declared via add_idf_component()
|
||||
instead of going through ESPHome's PlatformIO-library converter, on either
|
||||
toolchain. Elsewhere noise-c still goes through that converter via
|
||||
cg.add_library(): on the Arduino framework because arduino-esp32 depends on
|
||||
espressif/libsodium of its own, and off ESP32 because there are no IDF
|
||||
components at all. This drives the real to_code() coroutine so every branch of
|
||||
that decision is exercised end to end, not just mocked.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -26,6 +27,7 @@ from esphome.const import (
|
||||
KEY_TARGET_PLATFORM,
|
||||
Framework,
|
||||
Platform,
|
||||
Toolchain,
|
||||
)
|
||||
from esphome.core import CORE, ID
|
||||
|
||||
@@ -51,8 +53,9 @@ def fixture_encryption_key() -> str:
|
||||
return base64.b64encode(b"0" * 32).decode()
|
||||
|
||||
|
||||
def _setup_core(platform: Platform, framework: Framework) -> None:
|
||||
def _setup_core(platform: Platform, framework: Framework, toolchain: Toolchain) -> None:
|
||||
CORE.reset()
|
||||
CORE.toolchain = toolchain
|
||||
CORE.data[KEY_CORE] = {
|
||||
KEY_TARGET_PLATFORM: str(platform),
|
||||
KEY_TARGET_FRAMEWORK: str(framework),
|
||||
@@ -65,9 +68,10 @@ def test_to_code_esp32_idf_encryption_uses_managed_idf_components(
|
||||
encryption_key: str,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""On ESP32 + ESP-IDF, noise-c and libsodium are declared as managed IDF
|
||||
components (add_idf_component), not converted PlatformIO libraries."""
|
||||
_setup_core(Platform.ESP32, Framework.ESP_IDF)
|
||||
"""On ESP32 + the ESP-IDF toolchain, noise-c and libsodium are declared as
|
||||
managed IDF components (add_idf_component), not converted PlatformIO
|
||||
libraries."""
|
||||
_setup_core(Platform.ESP32, Framework.ESP_IDF, Toolchain.ESP_IDF)
|
||||
config = _build_config(encryption_key)
|
||||
CORE.component_ids.add("api_id")
|
||||
|
||||
@@ -96,7 +100,7 @@ def test_to_code_esp32_arduino_encryption_uses_add_library(
|
||||
"""On the Arduino framework, arduino-esp32 brings its own bundled
|
||||
espressif/libsodium, so noise-c must still go through the PlatformIO-
|
||||
library converter (cg.add_library) instead of add_idf_component()."""
|
||||
_setup_core(Platform.ESP32, Framework.ARDUINO)
|
||||
_setup_core(Platform.ESP32, Framework.ARDUINO, Toolchain.ESP_IDF)
|
||||
config = _build_config(encryption_key)
|
||||
CORE.component_ids.add("api_id")
|
||||
|
||||
@@ -117,13 +121,44 @@ def test_to_code_esp32_arduino_encryption_uses_add_library(
|
||||
add_idf_component_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_to_code_esp32_idf_platformio_toolchain_also_uses_managed_components(
|
||||
encryption_key: str,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""The ESP-IDF framework can also be built with the PlatformIO toolchain,
|
||||
and the managed components are used there too. The choice deliberately does
|
||||
not depend on the toolchain: wireguard splits on the same condition, and if
|
||||
the two ever disagree one of them converts a second libsodium next to the
|
||||
managed one, which IDF refuses to build."""
|
||||
_setup_core(Platform.ESP32, Framework.ESP_IDF, Toolchain.PLATFORMIO)
|
||||
config = _build_config(encryption_key)
|
||||
CORE.component_ids.add("api_id")
|
||||
|
||||
add_idf_component_calls: list[dict] = []
|
||||
monkeypatch.setattr(
|
||||
esp32,
|
||||
"add_idf_component",
|
||||
lambda **kwargs: add_idf_component_calls.append(kwargs),
|
||||
)
|
||||
add_library_mock = MagicMock()
|
||||
monkeypatch.setattr(cg, "add_library", add_library_mock)
|
||||
|
||||
asyncio.run(api.to_code(config))
|
||||
|
||||
assert add_idf_component_calls == [
|
||||
{"name": "esphome/noise-c", "ref": api.NOISE_C_VERSION},
|
||||
{"name": "esphome/libsodium", "ref": api.LIBSODIUM_VERSION},
|
||||
]
|
||||
add_library_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_to_code_non_esp32_encryption_uses_add_library(
|
||||
encryption_key: str,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""Off ESP32 entirely (e.g. host), noise-c always goes through the
|
||||
PlatformIO-library converter -- add_idf_component is ESP-IDF-only."""
|
||||
_setup_core(Platform.HOST, Framework.NATIVE)
|
||||
_setup_core(Platform.HOST, Framework.NATIVE, Toolchain.PLATFORMIO)
|
||||
config = _build_config(encryption_key)
|
||||
CORE.component_ids.add("api_id")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user