Prevent entities running multiple updates simultaneously (#6511)

* Protect entity for multible updates on same time.

* Address all comments / make update more robust

* fix unittest

* fix lint

* address comments
This commit is contained in:
Pascal Vizeli 2017-03-14 17:26:55 +01:00 committed by Paulus Schoutsen
parent c4e151f621
commit 5529d77c62
3 changed files with 132 additions and 7 deletions

View file

@ -1,8 +1,7 @@
"""Test the entity helper."""
# pylint: disable=protected-access
import asyncio
from unittest.mock import MagicMock
from unittest.mock import patch
from unittest.mock import MagicMock, patch
import pytest
@ -132,3 +131,68 @@ class TestHelpersEntity(object):
self.hass.block_till_done()
state = self.hass.states.get(self.entity.entity_id)
assert state.attributes.get(ATTR_DEVICE_CLASS) == 'test_class'
@asyncio.coroutine
def test_warn_slow_update(hass):
"""Warn we log when entity update takes a long time."""
update_call = False
@asyncio.coroutine
def async_update():
"""Mock async update."""
nonlocal update_call
update_call = True
mock_entity = entity.Entity()
mock_entity.hass = hass
mock_entity.entity_id = 'comp_test.test_entity'
mock_entity.async_update = async_update
with patch.object(hass.loop, 'call_later', MagicMock()) \
as mock_call:
yield from mock_entity.async_update_ha_state(True)
assert mock_call.called
assert len(mock_call.mock_calls) == 2
timeout, logger_method = mock_call.mock_calls[0][1][:2]
assert timeout == entity.SLOW_UPDATE_WARNING
assert logger_method == entity._LOGGER.warning
assert mock_call().cancel.called
assert update_call
@asyncio.coroutine
def test_warn_slow_update_with_exception(hass):
"""Warn we log when entity update takes a long time and trow exception."""
update_call = False
@asyncio.coroutine
def async_update():
"""Mock async update."""
nonlocal update_call
update_call = True
raise AssertionError("Fake update error")
mock_entity = entity.Entity()
mock_entity.hass = hass
mock_entity.entity_id = 'comp_test.test_entity'
mock_entity.async_update = async_update
with patch.object(hass.loop, 'call_later', MagicMock()) \
as mock_call:
yield from mock_entity.async_update_ha_state(True)
assert mock_call.called
assert len(mock_call.mock_calls) == 2
timeout, logger_method = mock_call.mock_calls[0][1][:2]
assert timeout == entity.SLOW_UPDATE_WARNING
assert logger_method == entity._LOGGER.warning
assert mock_call().cancel.called
assert update_call