hass-core/tests/components/websocket_api/test_messages.py
J. Nick Koston 4a3b40a3ef
Ensure websocket event serializer cache is effective if subscription iden differs (#42226)
Since someone websocket subscriptions will use an iden of 2 for
state_changed event (most comment), and some will use another
number for all events, the cache would not be used because the
iden number was different.  We now cache only the event and
use a fast replace to insert the iden number into the serailized
response.
2020-10-23 01:28:22 +02:00

98 lines
2.6 KiB
Python

"""Test Websocket API messages module."""
from homeassistant.components.websocket_api.messages import (
_cached_event_message as lru_event_cache,
cached_event_message,
message_to_json,
)
from homeassistant.const import EVENT_STATE_CHANGED
from homeassistant.core import callback
async def test_cached_event_message(hass):
"""Test that we cache event messages."""
events = []
@callback
def _event_listener(event):
events.append(event)
hass.bus.async_listen(EVENT_STATE_CHANGED, _event_listener)
hass.states.async_set("light.window", "on")
hass.states.async_set("light.window", "off")
await hass.async_block_till_done()
assert len(events) == 2
lru_event_cache.cache_clear()
msg0 = cached_event_message(2, events[0])
assert msg0 == cached_event_message(2, events[0])
msg1 = cached_event_message(2, events[1])
assert msg1 == cached_event_message(2, events[1])
assert msg0 != msg1
cache_info = lru_event_cache.cache_info()
assert cache_info.hits == 2
assert cache_info.misses == 2
assert cache_info.currsize == 2
cached_event_message(2, events[1])
cache_info = lru_event_cache.cache_info()
assert cache_info.hits == 3
assert cache_info.misses == 2
assert cache_info.currsize == 2
async def test_cached_event_message_with_different_idens(hass):
"""Test that we cache event messages when the subscrition idens differ."""
events = []
@callback
def _event_listener(event):
events.append(event)
hass.bus.async_listen(EVENT_STATE_CHANGED, _event_listener)
hass.states.async_set("light.window", "on")
await hass.async_block_till_done()
assert len(events) == 1
lru_event_cache.cache_clear()
msg0 = cached_event_message(2, events[0])
msg1 = cached_event_message(3, events[0])
msg2 = cached_event_message(4, events[0])
assert msg0 != msg1
assert msg0 != msg2
cache_info = lru_event_cache.cache_info()
assert cache_info.hits == 2
assert cache_info.misses == 1
assert cache_info.currsize == 1
async def test_message_to_json(caplog):
"""Test we can serialize websocket messages."""
json_str = message_to_json({"id": 1, "message": "xyz"})
assert json_str == '{"id": 1, "message": "xyz"}'
json_str2 = message_to_json({"id": 1, "message": _Unserializeable()})
assert (
json_str2
== '{"id": 1, "type": "result", "success": false, "error": {"code": "unknown_error", "message": "Invalid JSON in response"}}'
)
assert "Unable to serialize to JSON" in caplog.text
class _Unserializeable:
"""A class that cannot be serialized."""