Retry keyset cloud (#12270)
* Use less threads in helpers.event tests * Add helpers.event.async_call_later * Cloud: retry fetching keysetpull/12267/head
parent
a9412d27aa
commit
aad26599ae
|
@ -16,8 +16,7 @@ import voluptuous as vol
|
|||
|
||||
from homeassistant.const import (
|
||||
EVENT_HOMEASSISTANT_START, CONF_REGION, CONF_MODE, CONF_NAME, CONF_TYPE)
|
||||
from homeassistant.helpers import entityfilter
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers import entityfilter, config_validation as cv
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.util import dt as dt_util
|
||||
from homeassistant.components.alexa import smart_home as alexa_sh
|
||||
|
@ -105,12 +104,7 @@ def async_setup(hass, config):
|
|||
)
|
||||
|
||||
cloud = hass.data[DOMAIN] = Cloud(hass, **kwargs)
|
||||
|
||||
success = yield from cloud.initialize()
|
||||
|
||||
if not success:
|
||||
return False
|
||||
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, cloud.async_start)
|
||||
yield from http_api.async_setup(hass)
|
||||
return True
|
||||
|
||||
|
@ -192,19 +186,6 @@ class Cloud:
|
|||
|
||||
return self._gactions_config
|
||||
|
||||
@asyncio.coroutine
|
||||
def initialize(self):
|
||||
"""Initialize and load cloud info."""
|
||||
jwt_success = yield from self._fetch_jwt_keyset()
|
||||
|
||||
if not jwt_success:
|
||||
return False
|
||||
|
||||
self.hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_START, self._start_cloud)
|
||||
|
||||
return True
|
||||
|
||||
def path(self, *parts):
|
||||
"""Get config path inside cloud dir.
|
||||
|
||||
|
@ -234,8 +215,18 @@ class Cloud:
|
|||
'refresh_token': self.refresh_token,
|
||||
}, indent=4))
|
||||
|
||||
def _start_cloud(self, event):
|
||||
@asyncio.coroutine
|
||||
def async_start(self, _):
|
||||
"""Start the cloud component."""
|
||||
success = yield from self._fetch_jwt_keyset()
|
||||
|
||||
# Fetching keyset can fail if internet is not up yet.
|
||||
if not success:
|
||||
self.hass.helpers.async_call_later(5, self.async_start)
|
||||
return
|
||||
|
||||
def load_config():
|
||||
"""Load config."""
|
||||
# Ensure config dir exists
|
||||
path = self.hass.config.path(CONFIG_DIR)
|
||||
if not os.path.isdir(path):
|
||||
|
@ -243,10 +234,15 @@ class Cloud:
|
|||
|
||||
user_info = self.user_info_path
|
||||
if not os.path.isfile(user_info):
|
||||
return
|
||||
return None
|
||||
|
||||
with open(user_info, 'rt') as file:
|
||||
info = json.loads(file.read())
|
||||
return json.loads(file.read())
|
||||
|
||||
info = yield from self.hass.async_add_job(load_config)
|
||||
|
||||
if info is None:
|
||||
return
|
||||
|
||||
# Validate tokens
|
||||
try:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Helpers for listening to events."""
|
||||
from datetime import timedelta
|
||||
import functools as ft
|
||||
|
||||
from homeassistant.loader import bind_hass
|
||||
|
@ -219,6 +220,14 @@ track_point_in_utc_time = threaded_listener_factory(
|
|||
async_track_point_in_utc_time)
|
||||
|
||||
|
||||
@callback
|
||||
@bind_hass
|
||||
def async_call_later(hass, delay, action):
|
||||
"""Add a listener that is called in <delay>."""
|
||||
return async_track_point_in_utc_time(
|
||||
hass, action, dt_util.utcnow() + timedelta(seconds=delay))
|
||||
|
||||
|
||||
@callback
|
||||
@bind_hass
|
||||
def async_track_time_interval(hass, action, interval):
|
||||
|
|
|
@ -14,8 +14,8 @@ from tests.common import mock_coro
|
|||
@pytest.fixture
|
||||
def cloud_client(hass, test_client):
|
||||
"""Fixture that can fetch from the cloud client."""
|
||||
with patch('homeassistant.components.cloud.Cloud.initialize',
|
||||
return_value=mock_coro(True)):
|
||||
with patch('homeassistant.components.cloud.Cloud.async_start',
|
||||
return_value=mock_coro()):
|
||||
hass.loop.run_until_complete(async_setup_component(hass, 'cloud', {
|
||||
'cloud': {
|
||||
'mode': 'development',
|
||||
|
|
|
@ -87,7 +87,7 @@ def test_initialize_loads_info(mock_os, hass):
|
|||
|
||||
with patch('homeassistant.components.cloud.open', mopen, create=True), \
|
||||
patch('homeassistant.components.cloud.Cloud._decode_claims'):
|
||||
cl._start_cloud(None)
|
||||
yield from cl.async_start(None)
|
||||
|
||||
assert cl.id_token == 'test-id-token'
|
||||
assert cl.access_token == 'test-access-token'
|
||||
|
|
|
@ -266,8 +266,8 @@ def test_handler_alexa(hass):
|
|||
hass.states.async_set(
|
||||
'switch.test2', 'on', {'friendly_name': "Test switch 2"})
|
||||
|
||||
with patch('homeassistant.components.cloud.Cloud.initialize',
|
||||
return_value=mock_coro(True)):
|
||||
with patch('homeassistant.components.cloud.Cloud.async_start',
|
||||
return_value=mock_coro()):
|
||||
setup = yield from async_setup_component(hass, 'cloud', {
|
||||
'cloud': {
|
||||
'alexa': {
|
||||
|
@ -309,8 +309,8 @@ def test_handler_google_actions(hass):
|
|||
hass.states.async_set(
|
||||
'switch.test2', 'on', {'friendly_name': "Test switch 2"})
|
||||
|
||||
with patch('homeassistant.components.cloud.Cloud.initialize',
|
||||
return_value=mock_coro(True)):
|
||||
with patch('homeassistant.components.cloud.Cloud.async_start',
|
||||
return_value=mock_coro()):
|
||||
setup = yield from async_setup_component(hass, 'cloud', {
|
||||
'cloud': {
|
||||
'google_actions': {
|
||||
|
|
|
@ -7,10 +7,12 @@ from datetime import datetime, timedelta
|
|||
from astral import Astral
|
||||
import pytest
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.setup import setup_component
|
||||
import homeassistant.core as ha
|
||||
from homeassistant.const import MATCH_ALL
|
||||
from homeassistant.helpers.event import (
|
||||
async_call_later,
|
||||
track_point_in_utc_time,
|
||||
track_point_in_time,
|
||||
track_utc_time_change,
|
||||
|
@ -52,7 +54,7 @@ class TestEventHelpers(unittest.TestCase):
|
|||
runs = []
|
||||
|
||||
track_point_in_utc_time(
|
||||
self.hass, lambda x: runs.append(1), birthday_paulus)
|
||||
self.hass, callback(lambda x: runs.append(1)), birthday_paulus)
|
||||
|
||||
self._send_time_changed(before_birthday)
|
||||
self.hass.block_till_done()
|
||||
|
@ -68,14 +70,14 @@ class TestEventHelpers(unittest.TestCase):
|
|||
self.assertEqual(1, len(runs))
|
||||
|
||||
track_point_in_time(
|
||||
self.hass, lambda x: runs.append(1), birthday_paulus)
|
||||
self.hass, callback(lambda x: runs.append(1)), birthday_paulus)
|
||||
|
||||
self._send_time_changed(after_birthday)
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(2, len(runs))
|
||||
|
||||
unsub = track_point_in_time(
|
||||
self.hass, lambda x: runs.append(1), birthday_paulus)
|
||||
self.hass, callback(lambda x: runs.append(1)), birthday_paulus)
|
||||
unsub()
|
||||
|
||||
self._send_time_changed(after_birthday)
|
||||
|
@ -642,3 +644,22 @@ class TestEventHelpers(unittest.TestCase):
|
|||
self._send_time_changed(datetime(2014, 5, 2, 0, 0, 0))
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(0, len(specific_runs))
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_async_call_later(hass):
|
||||
"""Test calling an action later."""
|
||||
def action(): pass
|
||||
now = datetime(2017, 12, 19, 15, 40, 0, tzinfo=dt_util.UTC)
|
||||
|
||||
with patch('homeassistant.helpers.event'
|
||||
'.async_track_point_in_utc_time') as mock, \
|
||||
patch('homeassistant.util.dt.utcnow', return_value=now):
|
||||
remove = async_call_later(hass, 3, action)
|
||||
|
||||
assert len(mock.mock_calls) == 1
|
||||
p_hass, p_action, p_point = mock.mock_calls[0][1]
|
||||
assert hass is hass
|
||||
assert p_action is action
|
||||
assert p_point == now + timedelta(seconds=3)
|
||||
assert remove is mock()
|
||||
|
|
Loading…
Reference in New Issue