mirror of
https://github.com/esphome/esphome.git
synced 2026-10-04 10:09:13 +00:00
[socket] Compile the lookup and client link helpers only when required (#20002)
This commit is contained in:
@@ -140,6 +140,17 @@ def require_wake_loop_threadsafe() -> None:
|
||||
cg.add_define("USE_SOCKET_SELECT_SUPPORT")
|
||||
|
||||
|
||||
def require_ipv4_resolve() -> None:
|
||||
"""Compile the shared IPv4 lookup; call from a consumer's to_code."""
|
||||
cg.add_define("USE_SOCKET_IPV4_RESOLVE")
|
||||
|
||||
|
||||
def require_tcp_client_link() -> None:
|
||||
"""Compile the reconnecting TCP client link; call from a consumer's to_code."""
|
||||
require_ipv4_resolve()
|
||||
cg.add_define("USE_SOCKET_TCP_CLIENT_LINK")
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.SplitDefault(
|
||||
@@ -184,11 +195,14 @@ async def to_code(config: ConfigType) -> None:
|
||||
|
||||
|
||||
# Each implementation file is fully #ifdef'd on the define set in to_code
|
||||
# for the selected implementation.
|
||||
# for the selected implementation. The helper files compile only for
|
||||
# consumers that called the matching require_ function.
|
||||
FILTER_SOURCE_FILES = filter_source_files_from_defines(
|
||||
{
|
||||
"lwip_raw_tcp_impl.cpp": "USE_SOCKET_IMPL_LWIP_TCP",
|
||||
"bsd_sockets_impl.cpp": "USE_SOCKET_IMPL_BSD_SOCKETS",
|
||||
"lwip_sockets_impl.cpp": "USE_SOCKET_IMPL_LWIP_SOCKETS",
|
||||
"ipv4_resolve.cpp": "USE_SOCKET_IPV4_RESOLVE",
|
||||
"tcp_client_link.cpp": "USE_SOCKET_TCP_CLIENT_LINK",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -417,6 +417,8 @@
|
||||
#define USE_SENDSPIN_VISUALIZER
|
||||
#define USE_SENDSPIN_PORT 8928 // NOLINT
|
||||
#define USE_SOCKET_IMPL_BSD_SOCKETS
|
||||
#define USE_SOCKET_IPV4_RESOLVE
|
||||
#define USE_SOCKET_TCP_CLIENT_LINK
|
||||
#define USE_LWIP_FAST_SELECT
|
||||
|
||||
#define USE_SPEAKER
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# shadowing the stdlib module -- no test_*.py (Python-level) tests can live here.
|
||||
# required for cpp unit testing.
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import socket as socket_component
|
||||
from tests.testing_helpers import ComponentManifestOverride
|
||||
|
||||
|
||||
@@ -12,5 +13,7 @@ def override_manifest(manifest: ComponentManifestOverride) -> None:
|
||||
async def to_code_testing(config):
|
||||
await real_to_code(config)
|
||||
cg.add_define("USE_NETWORK_IPV6", True)
|
||||
# The gtests link against the filtered helper files.
|
||||
socket_component.require_tcp_client_link()
|
||||
|
||||
manifest.to_code = to_code_testing
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import socket
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.types import ConfigType
|
||||
@@ -18,5 +19,6 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
socket.require_ipv4_resolve()
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
||||
+2
@@ -1,4 +1,5 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import socket
|
||||
from esphome.components.const import CONF_HOST
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_PORT
|
||||
@@ -28,6 +29,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
socket.require_tcp_client_link()
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
cg.add(var.set_host(config[CONF_HOST]))
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
"""Tests for the socket component's source filtering and require functions."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from esphome.components import socket
|
||||
from esphome.core import Define
|
||||
|
||||
|
||||
def test_helper_files_filtered_until_required() -> None:
|
||||
"""ipv4_resolve.cpp and tcp_client_link.cpp compile only when required."""
|
||||
with patch("esphome.config_helpers.CORE") as mock_core:
|
||||
mock_core.defines = set()
|
||||
filtered = socket.FILTER_SOURCE_FILES()
|
||||
assert "ipv4_resolve.cpp" in filtered
|
||||
assert "tcp_client_link.cpp" in filtered
|
||||
|
||||
mock_core.defines = {Define("USE_SOCKET_IPV4_RESOLVE")}
|
||||
filtered = socket.FILTER_SOURCE_FILES()
|
||||
assert "ipv4_resolve.cpp" not in filtered
|
||||
assert "tcp_client_link.cpp" in filtered
|
||||
|
||||
mock_core.defines = {
|
||||
Define("USE_SOCKET_IPV4_RESOLVE"),
|
||||
Define("USE_SOCKET_TCP_CLIENT_LINK"),
|
||||
}
|
||||
filtered = socket.FILTER_SOURCE_FILES()
|
||||
assert "ipv4_resolve.cpp" not in filtered
|
||||
assert "tcp_client_link.cpp" not in filtered
|
||||
|
||||
|
||||
def test_require_tcp_client_link_pulls_in_the_resolver() -> None:
|
||||
"""require_tcp_client_link() sets both defines; the link reads the resolver."""
|
||||
with patch.object(socket.cg, "add_define") as add_define:
|
||||
socket.require_tcp_client_link()
|
||||
assert {call.args[0] for call in add_define.call_args_list} == {
|
||||
"USE_SOCKET_IPV4_RESOLVE",
|
||||
"USE_SOCKET_TCP_CLIENT_LINK",
|
||||
}
|
||||
Reference in New Issue
Block a user