Prefix the poll result enumerators, report a reset after connect as ECONNRESET, and test the set_sockaddr contract on host

This commit is contained in:
J. Nick Koston
2026-09-05 15:39:31 +02:00
parent 457e224e19
commit 329dec0e9a
7 changed files with 84 additions and 19 deletions
@@ -0,0 +1,18 @@
esphome:
name: socket-set-sockaddr
on_boot:
then:
- lambda: |-
// Exercise the contract callers rely on: 0 for text that is not an
// address, the sockaddr length otherwise, broadcast included
struct sockaddr_storage addr;
auto *sa = reinterpret_cast<struct sockaddr *>(&addr);
ESP_LOGI("test", "SET_SOCKADDR invalid=%u valid=%u broadcast=%u",
(unsigned) socket::set_sockaddr(sa, sizeof(addr), "not an address", 1234),
(unsigned) socket::set_sockaddr(sa, sizeof(addr), "192.0.2.1", 1234),
(unsigned) socket::set_sockaddr(sa, sizeof(addr), "255.255.255.255", 1234));
host:
api:
logger:
level: INFO
@@ -0,0 +1,45 @@
"""Integration test for the socket::set_sockaddr failure contract.
Callers skip an address when set_sockaddr returns 0, so text that is not an
address must return 0 while a real address, including the broadcast address
that inet_addr() would have reported as a failure, returns its length.
"""
import asyncio
import re
import pytest
from .types import APIClientConnectedFactory, RunCompiledFunction
@pytest.mark.asyncio
async def test_socket_set_sockaddr(
yaml_config: str,
run_compiled: RunCompiledFunction,
api_client_connected: APIClientConnectedFactory,
) -> None:
"""set_sockaddr reports an invalid address with 0 and accepts broadcast."""
loop = asyncio.get_running_loop()
result: asyncio.Future[tuple[int, int, int]] = loop.create_future()
def on_log_line(line: str) -> None:
match = re.search(
r"SET_SOCKADDR invalid=(\d+) valid=(\d+) broadcast=(\d+)", line
)
if match and not result.done():
result.set_result(tuple(int(g) for g in match.groups()))
async with (
run_compiled(yaml_config, line_callback=on_log_line),
api_client_connected() as client,
):
assert (await client.device_info()).name == "socket-set-sockaddr"
try:
invalid, valid, broadcast = await asyncio.wait_for(result, timeout=10.0)
except TimeoutError:
pytest.fail("SET_SOCKADDR marker never appeared")
assert invalid == 0
assert valid > 0
assert broadcast == valid