"""Integration test for API with VERY_VERBOSE logging to verify no buffer corruption.""" from __future__ import annotations import asyncio from typing import Any from aioesphomeapi import LogLevel import pytest from .types import APIClientConnectedFactory, RunCompiledFunction @pytest.mark.asyncio async def test_api_vv_logging( yaml_config: str, run_compiled: RunCompiledFunction, api_client_connected: APIClientConnectedFactory, ) -> None: """Test that VERY_VERBOSE logging doesn't cause buffer corruption with API messages.""" # Track that we're receiving VV log messages and sensor updates vv_logs_received = 0 sensor_updates_received = 0 errors_detected = [] def on_log(msg: Any) -> None: """Capture log messages.""" nonlocal vv_logs_received # msg is a SubscribeLogsResponse object with 'message' attribute # The message field is always bytes message_text = msg.message.decode("utf-8", errors="replace") # Only count VV logs specifically if "[VV]" in message_text: vv_logs_received += 1 # Check for assertion or error messages if "assert" in message_text.lower() or "error" in message_text.lower(): errors_detected.append(message_text) # Write, compile and run the ESPHome device async with run_compiled(yaml_config), api_client_connected() as client: # Subscribe to VERY_VERBOSE logs - this enables the code path that could cause corruption client.subscribe_logs(on_log, log_level=LogLevel.LOG_LEVEL_VERY_VERBOSE) # Wait for device to be ready device_info = await client.device_info() assert device_info is not None assert device_info.name == "vv-logging-test" # Subscribe to sensor states states = {} def on_state(state): nonlocal sensor_updates_received sensor_updates_received += 1 states[state.key] = state client.subscribe_states(on_state) # List entities to find our test sensors entity_info, _ = await client.list_entities_services() # Count sensors sensor_count = sum(1 for e in entity_info if hasattr(e, "unit_of_measurement")) assert sensor_count >= 10, f"Expected at least 10 sensors, got {sensor_count}" # Wait for sensor updates to flow with VV logging active # The sensors update every 50ms, so we should get many updates await asyncio.sleep(0.25) # Verify we received both VV logs and sensor updates assert vv_logs_received > 0, "Expected to receive VERY_VERBOSE log messages" assert sensor_updates_received > 10, ( f"Expected many sensor updates, got {sensor_updates_received}" ) # Check for any errors if errors_detected: pytest.fail(f"Errors detected during test: {errors_detected}") # The test passes if we didn't hit any assertions or buffer corruption