Fix flaky husqvarna_automower test with comprehensive race condition fix (#148911)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Franck Nijhof 2025-07-16 21:40:44 +02:00 committed by GitHub
parent 58bb2fa327
commit e8fca19335
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 11 deletions

View File

@ -70,6 +70,8 @@ class AutomowerCalendarEntity(AutomowerBaseEntity, CalendarEntity):
@property
def event(self) -> CalendarEvent | None:
"""Return the current or next upcoming event."""
if not self.available:
return None
schedule = self.mower_attributes.calendar
cursor = schedule.timeline.active_after(dt_util.now())
program_event = next(cursor, None)
@ -94,6 +96,8 @@ class AutomowerCalendarEntity(AutomowerBaseEntity, CalendarEntity):
This is only called when opening the calendar in the UI.
"""
if not self.available:
return []
schedule = self.mower_attributes.calendar
cursor = schedule.timeline.overlapping(
start_date,

View File

@ -114,6 +114,11 @@ class AutomowerBaseEntity(CoordinatorEntity[AutomowerDataUpdateCoordinator]):
"""Get the mower attributes of the current mower."""
return self.coordinator.data[self.mower_id]
@property
def available(self) -> bool:
"""Return True if the device is available."""
return super().available and self.mower_id in self.coordinator.data
class AutomowerAvailableEntity(AutomowerBaseEntity):
"""Replies available when the mower is connected."""

View File

@ -312,8 +312,9 @@ async def test_coordinator_automatic_registry_cleanup(
dr.async_entries_for_config_entry(device_registry, entry.entry_id)
)
# Remove mower 2 and check if it worked
mower2 = values.pop("1234")
mock_automower_client.get_status.return_value = values
values_copy = deepcopy(values)
mower2 = values_copy.pop("1234")
mock_automower_client.get_status.return_value = values_copy
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
@ -327,8 +328,9 @@ async def test_coordinator_automatic_registry_cleanup(
== current_devices - 1
)
# Add mower 2 and check if it worked
values["1234"] = mower2
mock_automower_client.get_status.return_value = values
values_copy = deepcopy(values)
values_copy["1234"] = mower2
mock_automower_client.get_status.return_value = values_copy
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
@ -342,8 +344,9 @@ async def test_coordinator_automatic_registry_cleanup(
)
# Remove mower 1 and check if it worked
mower1 = values.pop(TEST_MOWER_ID)
mock_automower_client.get_status.return_value = values
values_copy = deepcopy(values)
mower1 = values_copy.pop(TEST_MOWER_ID)
mock_automower_client.get_status.return_value = values_copy
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
@ -357,11 +360,9 @@ async def test_coordinator_automatic_registry_cleanup(
== current_devices - 1
)
# Add mower 1 and check if it worked
values[TEST_MOWER_ID] = mower1
mock_automower_client.get_status.return_value = values
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
values_copy = deepcopy(values)
values_copy[TEST_MOWER_ID] = mower1
mock_automower_client.get_status.return_value = values_copy
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()