Build the shared rp2350 target on rpipico2w and test the slot accounting

This commit is contained in:
J. Nick Koston
2026-08-10 17:00:43 -05:00
parent 0429d05859
commit 5c2c11f6cb
4 changed files with 68 additions and 10 deletions
+15 -9
View File
@@ -57,17 +57,23 @@ def consume_connection_slots(
return _consume_connection_slots
def validate_connection_slots() -> None:
"""Fail when consumers claimed more slots than the platform cap."""
# Skip in testing mode to allow component grouping (esp32_ble parity).
if CORE.testing_mode:
return
used = CORE.data.get(KEY_RP2040_BLE, {}).get(KEY_USED_CONNECTION_SLOTS, [])
if len(used) > MAX_CONNECTIONS:
raise cv.Invalid(
f"BLE components require {len(used)} connection slots but the "
f"rp2 maximum is {MAX_CONNECTIONS}. "
f"Components: {', '.join(used)}"
)
def _final_validate(config: ConfigType) -> ConfigType:
_validate_board(config)
# Skip in testing mode to allow component grouping (esp32_ble parity).
if not CORE.testing_mode:
used = CORE.data.get(KEY_RP2040_BLE, {}).get(KEY_USED_CONNECTION_SLOTS, [])
if len(used) > MAX_CONNECTIONS:
raise cv.Invalid(
f"BLE components require {len(used)} connection slots but the "
f"rp2 maximum is {MAX_CONNECTIONS}. "
f"Components: {', '.join(used)}"
)
validate_connection_slots()
return config
@@ -0,0 +1,41 @@
"""Connection-slot accounting: consumers claim against MAX_CONNECTIONS and
final validation rejects over-subscription with the consumer list."""
from __future__ import annotations
from collections.abc import Callable
from pathlib import Path
import pytest
from esphome import config_validation as cv
from esphome.components import rp2040_ble
from esphome.core import CORE
def test_proxy_claims_its_slots_through_the_shared_accounting(
generate_main: Callable[[str | Path], str],
component_config_path: Callable[[str], Path],
) -> None:
# A default (3-slot) proxy build records one claim per slot, attributed
# to the consumer, and passes final validation.
generate_main(component_config_path("rp2_proxy_default.yaml"))
used = CORE.data[rp2040_ble.KEY_RP2040_BLE][rp2040_ble.KEY_USED_CONNECTION_SLOTS]
assert used == ["bluetooth_proxy"] * 3
def test_oversubscription_is_rejected_with_the_consumer_list() -> None:
# No YAML shape reaches this today (the proxy schema caps at the same
# limit); the guard exists for a second consumer such as ble_client.
rp2040_ble.consume_connection_slots(3, "bluetooth_proxy")({})
rp2040_ble.consume_connection_slots(1, "ble_client")({})
with pytest.raises(
cv.Invalid,
match=r"4 connection slots.*maximum is 3.*bluetooth_proxy.*ble_client",
):
rp2040_ble.validate_connection_slots()
def test_at_cap_passes() -> None:
rp2040_ble.consume_connection_slots(3, "bluetooth_proxy")({})
rp2040_ble.validate_connection_slots()
@@ -0,0 +1,9 @@
# Pico 2 W build of the full proxy: links the rp2350 framework archive, so
# the pool --wrap overrides and their per-architecture layout asserts are
# exercised for this chip too (see test.rp2040-ard.yaml for the slot shape).
packages:
common: !include common.yaml
rp2_ble_tracker:
bluetooth_proxy:
@@ -2,8 +2,10 @@ esphome:
name: componenttestrp2040pico2ard
friendly_name: $component_name
# rpipico2w: superset of rpipico2 with the CYW43 radio, so wireless
# components (wifi, BLE) can share this target too.
rp2:
board: rpipico2
board: rpipico2w
logger:
level: VERY_VERBOSE