[tests] Drop the external component path replacements the yaml_config fixture already does (#21149)

This commit is contained in:
J. Nick Koston
2026-10-20 08:50:38 -04:00
committed by GitHub
parent 6c4a42c069
commit b18a5b09e7
28 changed files with 0 additions and 267 deletions
@@ -3,7 +3,6 @@
from __future__ import annotations
import asyncio
from pathlib import Path
import re
from aioesphomeapi import UserService, UserServiceArgType
@@ -19,16 +18,6 @@ async def test_api_custom_services(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test CustomAPIDevice services work correctly with custom_services: true."""
# Get the path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
# Track log messages
-11
View File
@@ -3,7 +3,6 @@
from __future__ import annotations
import asyncio
from pathlib import Path
import pytest
@@ -17,16 +16,6 @@ async def test_crc8_helper(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test the CRC8 helper function through integration testing."""
# Get the path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Track test completion with asyncio.Event
test_complete = asyncio.Event()
@@ -3,7 +3,6 @@
from __future__ import annotations
import asyncio
from pathlib import Path
import re
import pytest
@@ -18,16 +17,6 @@ async def test_gpio_expander_cache(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test gpio_expander::CachedGpioExpander correctly calls hardware functions."""
# Get the path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
logs_done = asyncio.Event()
# Patterns to match in logs - match any variation of digital_read
@@ -11,7 +11,6 @@ in 2026.11.0 when the deprecated ClimateTraits setters are removed.
from __future__ import annotations
import asyncio
from pathlib import Path
import aioesphomeapi
from aioesphomeapi import ClimateInfo
@@ -28,13 +27,6 @@ async def test_legacy_climate_compat(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test that deprecated ClimateTraits custom mode setters still work end-to-end."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
async with run_compiled(yaml_config), api_client_connected() as client:
@@ -10,7 +10,6 @@ in 2026.11.0 when the deprecated FanTraits setters are removed.
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import FanInfo, FanState
import pytest
@@ -25,13 +24,6 @@ async def test_legacy_fan_compat(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test that deprecated FanTraits preset mode setters still work end-to-end."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
async with run_compiled(yaml_config), api_client_connected() as client:
entities, _ = await client.list_entities_services()
@@ -3,7 +3,6 @@
from __future__ import annotations
import asyncio
from pathlib import Path
import re
import pytest
@@ -18,16 +17,6 @@ async def test_loop_disable_enable(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test that components can disable and enable their loop() method."""
# Get the absolute path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Track log messages and events
log_messages: list[str] = []
@@ -7,7 +7,6 @@ takes the separate defer queue on multi-threaded builds.
from __future__ import annotations
import asyncio
from pathlib import Path
import re
from aioesphomeapi import ButtonInfo
@@ -23,13 +22,6 @@ async def test_scheduler_background_wake(
run_compiled: RunCompiledFunction,
api_client_connected: APIClientConnectedFactory,
) -> None:
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
results: dict[int, asyncio.Future[tuple[int, int]]] = {
100: loop.create_future(),
@@ -1,7 +1,6 @@
"""Test that triggers the bulk cleanup path when to_remove_ > MAX_LOGICALLY_DELETED_ITEMS."""
import asyncio
from pathlib import Path
import re
from aioesphomeapi import UserService
@@ -18,16 +17,6 @@ async def test_scheduler_bulk_cleanup(
) -> None:
"""Test that bulk cleanup path is triggered when many items are cancelled."""
# Get the absolute path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Create a future to signal test completion
loop = asyncio.get_event_loop()
test_complete_future: asyncio.Future[None] = loop.create_future()
@@ -1,7 +1,6 @@
"""Stress test for defer() thread safety with multiple threads."""
import asyncio
from pathlib import Path
import re
from aioesphomeapi import UserService
@@ -18,16 +17,6 @@ async def test_scheduler_defer_stress(
) -> None:
"""Test that defer() doesn't crash when called rapidly from multiple threads."""
# Get the absolute path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Create a future to signal test completion
loop = asyncio.get_event_loop()
test_complete_future: asyncio.Future[None] = loop.create_future()
@@ -1,7 +1,6 @@
"""Stress test for heap scheduler thread safety with multiple threads."""
import asyncio
from pathlib import Path
import re
from aioesphomeapi import UserService
@@ -18,16 +17,6 @@ async def test_scheduler_heap_stress(
) -> None:
"""Test that set_timeout/set_interval doesn't crash when called rapidly from multiple threads."""
# Get the absolute path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Create a future to signal test completion
loop = asyncio.get_running_loop()
test_complete_future: asyncio.Future[None] = loop.create_future()
@@ -3,7 +3,6 @@
from __future__ import annotations
import asyncio
from pathlib import Path
import re
import pytest
@@ -18,12 +17,6 @@ async def test_scheduler_loop_phase_timeout(
write_yaml_config: ConfigWriter,
compile_esphome: CompileFunction,
) -> None:
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
config_path = await write_yaml_config(yaml_config)
binary_path = await compile_esphome(config_path)
@@ -1,7 +1,6 @@
"""Rapid cancellation test - schedule and immediately cancel timeouts with string names."""
import asyncio
from pathlib import Path
import re
from aioesphomeapi import UserService
@@ -18,16 +17,6 @@ async def test_scheduler_rapid_cancellation(
) -> None:
"""Test rapid schedule/cancel cycles that might expose race conditions."""
# Get the absolute path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Create a future to signal test completion
loop = asyncio.get_running_loop()
test_complete_future: asyncio.Future[None] = loop.create_future()
@@ -1,7 +1,6 @@
"""Test for recursive timeout scheduling - scheduling timeouts from within timeout callbacks."""
import asyncio
from pathlib import Path
from aioesphomeapi import UserService
import pytest
@@ -17,16 +16,6 @@ async def test_scheduler_recursive_timeout(
) -> None:
"""Test that scheduling timeouts from within timeout callbacks works correctly."""
# Get the absolute path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Create a future to signal test completion
loop = asyncio.get_running_loop()
test_complete_future: asyncio.Future[None] = loop.create_future()
@@ -1,7 +1,6 @@
"""Simultaneous callbacks test - schedule many callbacks for the same time from multiple threads."""
import asyncio
from pathlib import Path
import re
from aioesphomeapi import UserService
@@ -18,16 +17,6 @@ async def test_scheduler_simultaneous_callbacks(
) -> None:
"""Test scheduling many callbacks for the exact same time from multiple threads."""
# Get the absolute path to the external components directory
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
# Replace the placeholder in the YAML config with the actual path
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Create a future to signal test completion
loop = asyncio.get_running_loop()
test_complete_future: asyncio.Future[None] = loop.create_future()
@@ -3,7 +3,6 @@
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import EntityState, SensorInfo
import pytest
@@ -19,13 +18,6 @@ async def test_uart_mock_bl0906_stray_rx(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""A stray received byte does not stop the read cycle."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
lines: list[str] = []
states: dict[int, EntityState] = {}
@@ -9,7 +9,6 @@ from __future__ import annotations
import asyncio
import math
from pathlib import Path
import re
from aioesphomeapi import EntityState, SensorInfo
@@ -30,13 +29,6 @@ async def test_uart_mock_dfrobot_sen0465(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Boot sets passive mode and the alarm before the first reading."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
alarm_set: asyncio.Future[re.Match[str]] = loop.create_future()
lines: list[str] = []
@@ -7,7 +7,6 @@ reaches the module as setRange followed by saveConfig.
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import BinarySensorInfo, EntityState, NumberInfo, TextSensorInfo
import pytest
@@ -23,13 +22,6 @@ async def test_uart_mock_dfrobot_sen0609(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Boot reads the module's settings; a number change is written and saved."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
saved = loop.create_future()
@@ -19,7 +19,6 @@ test_uart_mock_ld2410_engineering (engineering mode):
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import ButtonInfo
import pytest
@@ -35,14 +34,6 @@ async def test_uart_mock_ld2410(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test LD2410 data parsing with happy path, garbage, overflow, and recovery."""
# Replace external component path placeholder
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
# Track overflow warning in logs
@@ -184,13 +175,6 @@ async def test_uart_mock_ld2410_engineering(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test LD2410 engineering mode with per-gate energy, light, and multi-byte distance."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
collector = SensorStateCollector(
sensor_names=[
"moving_distance",
@@ -9,7 +9,6 @@ The ACKs are synthetic, built from the layout the component parses, not device c
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import (
ButtonInfo,
@@ -54,13 +53,6 @@ async def test_uart_mock_ld2410_query_ack(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test a data frame, then a query ACK with the footer bytes in its values."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
ack_errors: list[str] = []
waited_for_frame_end = loop.create_future()
@@ -20,7 +20,6 @@ test_uart_mock_ld2420_simple (simple mode):
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import ButtonInfo
import pytest
@@ -36,14 +35,6 @@ async def test_uart_mock_ld2420(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test LD2420 energy mode: happy path, truncated frame, overflow, and recovery."""
# Replace external component path placeholder
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
# Track overflow warning in logs
@@ -167,13 +158,6 @@ async def test_uart_mock_ld2420_simple(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test LD2420 simple mode: happy path, overflow, and 16-digit bug trigger."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
# Track overflow warning in logs
@@ -18,7 +18,6 @@ test_uart_mock_ld2450:
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import ButtonInfo
import pytest
@@ -34,14 +33,6 @@ async def test_uart_mock_ld2450(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test LD2450 data parsing with happy path, garbage, overflow, and recovery."""
# Replace external component path placeholder
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
# Track overflow warning in logs
@@ -8,7 +8,6 @@ Tests:
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import BinarySensorInfo, BinarySensorState, ButtonInfo, EntityState
import pytest
@@ -27,13 +26,6 @@ async def test_uart_mock_ld2450_has_target_only(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test has_target with no sensor platform and no presence_timeout number."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
async with (
run_compiled(yaml_config),
api_client_connected() as client,
@@ -8,7 +8,6 @@ Tests:
from __future__ import annotations
import asyncio
from pathlib import Path
import socket
import struct
@@ -37,12 +36,6 @@ async def test_uart_mock_ld2450_polygon_zone_restore(
) -> None:
"""Test that polygon zones are restored after a restart, and invalid saved polygons are rejected."""
port, port_socket = reserved_tcp_port
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
clear_host_prefs(DEVICE_NAME)
binary_path = await compile_esphome(await write_yaml_config(yaml_config))
@@ -8,7 +8,6 @@ Tests:
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import (
BinarySensorInfo,
@@ -38,12 +37,6 @@ async def test_uart_mock_ld2450_polygon_zone_timeout(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test that polygon zone presence follows presence_timeout."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# The polygon and presence_timeout are saved, so a previous run would otherwise restore them
clear_host_prefs(DEVICE_NAME)
@@ -11,7 +11,6 @@ Tests:
from __future__ import annotations
import asyncio
from pathlib import Path
import re
from aioesphomeapi import (
@@ -44,12 +43,6 @@ async def test_uart_mock_ld2450_polygon_zones(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test LD2450 polygon zone configuration and presence detection."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
# Polygons are saved, so a previous run would otherwise restore them
clear_host_prefs(DEVICE_NAME)
@@ -15,7 +15,6 @@ test_uart_mock_ld2460:
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import ButtonInfo
import pytest
@@ -31,13 +30,6 @@ async def test_uart_mock_ld2460(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test LD2460 frame parsing with the datasheet frames, garbage and overflow."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
overflow_seen = loop.create_future()
tx_log_lines: list[str] = []
@@ -12,7 +12,6 @@ Phases, all injected after the Start Scenario button press:
from __future__ import annotations
import asyncio
from pathlib import Path
from aioesphomeapi import ButtonInfo
import pytest
@@ -66,13 +65,6 @@ async def test_uart_mock_pylontech(
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test pylontech parsing with happy path, garbage, overflow and recovery."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
overflow_lines: list[str] = []
rejected_lines: list[str] = []
@@ -20,7 +20,6 @@ With the fix, delta>=1 (the wake forces Phase B within one tick of the wake).
from __future__ import annotations
import asyncio
from pathlib import Path
import re
import pytest
@@ -37,13 +36,6 @@ async def test_wake_loop_forces_phase_b(
"""A wake_loop_threadsafe() call from a background thread must trigger the
component phase within the next tick, even when loop_interval_ is raised
well above the observation window."""
external_components_path = str(
Path(__file__).parent / "fixtures" / "external_components"
)
yaml_config = yaml_config.replace(
"EXTERNAL_COMPONENT_PATH", external_components_path
)
loop = asyncio.get_running_loop()
result: asyncio.Future[tuple[int, int]] = loop.create_future()