Skip to content

Commit

Permalink
Fix OwnTracks race condition (#24303)
Browse files Browse the repository at this point in the history
* Fix OwnTracks race condition

* Lint
  • Loading branch information
balloob authored Jun 4, 2019
1 parent 6d28008 commit df1da75
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
12 changes: 11 additions & 1 deletion homeassistant/components/owntracks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def __init__(self, hass, secret, max_gps_accuracy, import_waypoints,
self.region_mapping = region_mapping
self.events_only = events_only
self.mqtt_topic = mqtt_topic
self._pending_msg = []

@callback
def async_valid_accuracy(self, message):
Expand Down Expand Up @@ -222,10 +223,19 @@ def async_valid_accuracy(self, message):

return True

@callback
def set_async_see(self, func):
"""Set a new async_see function."""
self.async_see = func
for msg in self._pending_msg:
func(**msg)
self._pending_msg.clear()

# pylint: disable=method-hidden
@callback
def async_see(self, **data):
"""Send a see message to the device tracker."""
raise NotImplementedError
self._pending_msg.append(data)

@callback
def async_see_beacons(self, hass, dev_id, kwargs_param):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/owntracks/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def _receive_data(dev_id, **data):
)
async_add_entities([entity])

hass.data[OT_DOMAIN]['context'].async_see = _receive_data
hass.data[OT_DOMAIN]['context'].set_async_see(_receive_data)

# Restore previously loaded devices
dev_reg = await device_registry.async_get_registry(hass)
Expand Down
23 changes: 22 additions & 1 deletion tests/components/owntracks/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

from homeassistant.setup import async_setup_component

from homeassistant.components import owntracks
from tests.common import mock_component, MockConfigEntry

MINIMAL_LOCATION_MESSAGE = {
Expand Down Expand Up @@ -160,3 +160,24 @@ def test_returns_error_missing_device(mock_client):

json = yield from resp.json()
assert json == []


def test_context_delivers_pending_msg():
"""Test that context is able to hold pending messages while being init."""
context = owntracks.OwnTracksContext(
None, None, None, None, None, None, None, None
)
context.async_see(hello='world')
context.async_see(world='hello')
received = []

context.set_async_see(lambda **data: received.append(data))

assert len(received) == 2
assert received[0] == {'hello': 'world'}
assert received[1] == {'world': 'hello'}

received.clear()

context.set_async_see(lambda **data: received.append(data))
assert len(received) == 0

0 comments on commit df1da75

Please sign in to comment.