Avoid checking for polling if an entity fails to add (#115159)

* Avoid checking for polling if an entity fails to add

* no need to do protected access

* no need to do protected access

* no need to do protected access

* no need to do protected access

* coverage

* fix test

* fix

* broken one must be first
pull/115164/head
J. Nick Koston 2024-04-07 15:25:55 -10:00 committed by GitHub
parent 6b4457043d
commit 89a2c89fe2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 2 deletions

View File

@ -631,7 +631,16 @@ class EntityPlatform:
if ( if (
(self.config_entry and self.config_entry.pref_disable_polling) (self.config_entry and self.config_entry.pref_disable_polling)
or self._async_unsub_polling is not None or self._async_unsub_polling is not None
or not any(entity.should_poll for entity in entities) or not any(
# Entity may have failed to add or called `add_to_platform_abort`
# so we check if the entity is in self.entities before
# checking `entity.should_poll` since `should_poll` may need to
# check `self.hass` which will be `None` if the entity did not add
entity.entity_id
and entity.entity_id in self.entities
and entity.should_poll
for entity in entities
)
): ):
return return

View File

@ -5,7 +5,7 @@ from collections.abc import Iterable
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Any from typing import Any
from unittest.mock import ANY, Mock, patch from unittest.mock import ANY, AsyncMock, Mock, patch
import pytest import pytest
@ -78,6 +78,40 @@ async def test_polling_only_updates_entities_it_should_poll(
assert poll_ent.async_update.called assert poll_ent.async_update.called
async def test_polling_check_works_if_entity_add_fails(
hass: HomeAssistant,
) -> None:
"""Test the polling check works if an entity add fails."""
component = EntityComponent(_LOGGER, DOMAIN, hass, timedelta(seconds=20))
await component.async_setup({})
class MockEntityNeedsSelfHassInShouldPoll(MockEntity):
"""Mock entity that needs self.hass in should_poll."""
@property
def should_poll(self) -> bool:
"""Return True if entity has to be polled."""
return self.hass.data is not None
working_poll_ent = MockEntityNeedsSelfHassInShouldPoll(should_poll=True)
working_poll_ent.async_update = AsyncMock()
broken_poll_ent = MockEntityNeedsSelfHassInShouldPoll(should_poll=True)
broken_poll_ent.async_update = AsyncMock(side_effect=Exception("Broken"))
await component.async_add_entities(
[broken_poll_ent, working_poll_ent], update_before_add=True
)
working_poll_ent.async_update.reset_mock()
broken_poll_ent.async_update.reset_mock()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=20))
await hass.async_block_till_done(wait_background_tasks=True)
assert not broken_poll_ent.async_update.called
assert working_poll_ent.async_update.called
async def test_polling_disabled_by_config_entry(hass: HomeAssistant) -> None: async def test_polling_disabled_by_config_entry(hass: HomeAssistant) -> None:
"""Test the polling of only updated entities.""" """Test the polling of only updated entities."""
entity_platform = MockEntityPlatform(hass) entity_platform = MockEntityPlatform(hass)