Fix flakey ESPHome dashboard tests (attempt 2) (#143123)

These tests do not need a config entry, only the integration
to be set up. Since I cannot replicate the issue locally after
1000 runs, I switched it to use async_setup_component to minimize
the potential problem area and hopefully fix the flakey test

I also modified the test to explictly set up hassio to ensure
the patch is effective since we have to patch a late import

last observed flake: https://github.com/home-assistant/core/actions/runs/14503715101/job/40689452294?pr=143106
This commit is contained in:
J. Nick Koston 2025-04-16 20:36:34 -10:00 committed by GitHub
parent bf69d4e0a8
commit 6a36fc75cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -6,10 +6,16 @@ from unittest.mock import patch
from aioesphomeapi import DeviceInfo, InvalidAuthAPIError from aioesphomeapi import DeviceInfo, InvalidAuthAPIError
import pytest import pytest
from homeassistant.components.esphome import CONF_NOISE_PSK, coordinator, dashboard from homeassistant.components.esphome import (
CONF_NOISE_PSK,
DOMAIN,
coordinator,
dashboard,
)
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
from homeassistant.setup import async_setup_component
from . import VALID_NOISE_PSK from . import VALID_NOISE_PSK
@ -34,7 +40,6 @@ async def test_dashboard_storage(
async def test_restore_dashboard_storage( async def test_restore_dashboard_storage(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
) -> None: ) -> None:
"""Restore dashboard url and slug from storage.""" """Restore dashboard url and slug from storage."""
@ -47,14 +52,13 @@ async def test_restore_dashboard_storage(
with patch.object( with patch.object(
dashboard, "async_get_or_create_dashboard_manager" dashboard, "async_get_or_create_dashboard_manager"
) as mock_get_or_create: ) as mock_get_or_create:
await hass.config_entries.async_setup(mock_config_entry.entry_id) await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done() await hass.async_block_till_done()
assert mock_get_or_create.call_count == 1 assert mock_get_or_create.call_count == 1
async def test_restore_dashboard_storage_end_to_end( async def test_restore_dashboard_storage_end_to_end(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
) -> None: ) -> None:
"""Restore dashboard url and slug from storage.""" """Restore dashboard url and slug from storage."""
@ -72,15 +76,13 @@ async def test_restore_dashboard_storage_end_to_end(
"homeassistant.components.esphome.coordinator.ESPHomeDashboardAPI" "homeassistant.components.esphome.coordinator.ESPHomeDashboardAPI"
) as mock_dashboard_api, ) as mock_dashboard_api,
): ):
await hass.config_entries.async_setup(mock_config_entry.entry_id) await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done() await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.LOADED
assert mock_dashboard_api.mock_calls[0][1][0] == "http://new-host:6052" assert mock_dashboard_api.mock_calls[0][1][0] == "http://new-host:6052"
async def test_restore_dashboard_storage_skipped_if_addon_uninstalled( async def test_restore_dashboard_storage_skipped_if_addon_uninstalled(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
caplog: pytest.LogCaptureFixture, caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
@ -103,27 +105,25 @@ async def test_restore_dashboard_storage_skipped_if_addon_uninstalled(
return_value={}, return_value={},
), ),
): ):
await hass.config_entries.async_setup(mock_config_entry.entry_id) await async_setup_component(hass, "hassio", {})
await hass.async_block_till_done()
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done() await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.LOADED
await hass.async_block_till_done() # wait for dashboard setup
assert "test-slug is no longer installed" in caplog.text assert "test-slug is no longer installed" in caplog.text
assert not mock_dashboard_api.called assert not mock_dashboard_api.called
async def test_setup_dashboard_fails( async def test_setup_dashboard_fails(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
) -> None: ) -> None:
"""Test that nothing is stored on failed dashboard setup when there was no dashboard before.""" """Test that nothing is stored on failed dashboard setup when there was no dashboard before."""
with patch.object( with patch.object(
coordinator.ESPHomeDashboardAPI, "get_devices", side_effect=TimeoutError coordinator.ESPHomeDashboardAPI, "get_devices", side_effect=TimeoutError
) as mock_get_devices: ) as mock_get_devices:
await hass.config_entries.async_setup(mock_config_entry.entry_id) await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done() await hass.async_block_till_done()
await dashboard.async_set_dashboard_info(hass, "test-slug", "test-host", 6052) await dashboard.async_set_dashboard_info(hass, "test-slug", "test-host", 6052)
assert mock_config_entry.state is ConfigEntryState.LOADED
assert mock_get_devices.call_count == 1 assert mock_get_devices.call_count == 1
# The dashboard addon might recover later so we still # The dashboard addon might recover later so we still