1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-27 14:31:13 +00:00

Migrate updater to aiohttp (#7387)

* Migrate updater to aiohttp

* Fix tests

* Update updater.py

* Docs
This commit is contained in:
Paulus Schoutsen
2017-05-01 23:29:01 -07:00
committed by GitHub
parent da2521a299
commit 8ea6c7319a
4 changed files with 222 additions and 164 deletions

View File

@@ -1,132 +1,158 @@
"""The tests for the Updater component."""
from datetime import datetime, timedelta
import unittest
from unittest.mock import patch
import os
import asyncio
from datetime import timedelta
from unittest.mock import patch, Mock
import requests
import requests_mock
import voluptuous as vol
from freezegun import freeze_time
import pytest
from homeassistant.setup import setup_component
from homeassistant.setup import async_setup_component
from homeassistant.components import updater
from tests.common import (
assert_setup_component, fire_time_changed, get_test_home_assistant)
import homeassistant.util.dt as dt_util
from tests.common import async_fire_time_changed, mock_coro
NEW_VERSION = '10000.0'
# We need to use a 'real' looking version number to load the updater component
MOCK_CURRENT_VERSION = '10.0'
MOCK_VERSION = '10.0'
MOCK_DEV_VERSION = '10.0.dev0'
MOCK_HUUID = 'abcdefg'
MOCK_RESPONSE = {
'version': '0.15',
'release-notes': 'https://home-assistant.io'
}
class TestUpdater(unittest.TestCase):
"""Test the Updater component."""
@pytest.fixture
def mock_get_newest_version():
"""Fixture to mock get_newest_version."""
with patch('homeassistant.components.updater.get_newest_version') as mock:
yield mock
hass = None
def setup_method(self, _):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
@pytest.fixture
def mock_get_uuid():
"""Fixture to mock get_uuid."""
with patch('homeassistant.components.updater._load_uuid') as mock:
yield mock
def teardown_method(self, _):
"""Stop everything that was started."""
self.hass.stop()
@patch('homeassistant.components.updater.get_newest_version')
def test_new_version_shows_entity_on_start( # pylint: disable=invalid-name
self, mock_get_newest_version):
"""Test if new entity is created if new version is available."""
mock_get_newest_version.return_value = (NEW_VERSION, '')
updater.CURRENT_VERSION = MOCK_CURRENT_VERSION
@asyncio.coroutine
@freeze_time("Mar 15th, 2017")
def test_new_version_shows_entity_after_hour(hass, mock_get_uuid,
mock_get_newest_version):
"""Test if new entity is created if new version is available."""
mock_get_uuid.return_value = MOCK_HUUID
mock_get_newest_version.return_value = mock_coro((NEW_VERSION, ''))
with assert_setup_component(1) as config:
setup_component(self.hass, updater.DOMAIN, {updater.DOMAIN: {}})
_dt = datetime.now() + timedelta(hours=1)
assert config['updater'] == {'reporting': True}
res = yield from async_setup_component(
hass, updater.DOMAIN, {updater.DOMAIN: {}})
assert res, 'Updater failed to setup'
for secs in [-1, 0, 1]:
fire_time_changed(self.hass, _dt + timedelta(seconds=secs))
self.hass.block_till_done()
with patch('homeassistant.components.updater.CURRENT_VERSION',
MOCK_VERSION):
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(hours=1))
yield from hass.async_block_till_done()
self.assertTrue(self.hass.states.is_state(
updater.ENTITY_ID, NEW_VERSION))
assert hass.states.is_state(updater.ENTITY_ID, NEW_VERSION)
@patch('homeassistant.components.updater.get_newest_version')
def test_no_entity_on_same_version( # pylint: disable=invalid-name
self, mock_get_newest_version):
"""Test if no entity is created if same version."""
mock_get_newest_version.return_value = (MOCK_CURRENT_VERSION, '')
updater.CURRENT_VERSION = MOCK_CURRENT_VERSION
with assert_setup_component(1) as config:
assert setup_component(
self.hass, updater.DOMAIN, {updater.DOMAIN: {}})
_dt = datetime.now() + timedelta(hours=1)
assert config['updater'] == {'reporting': True}
@asyncio.coroutine
@freeze_time("Mar 15th, 2017")
def test_same_version_not_show_entity(hass, mock_get_uuid,
mock_get_newest_version):
"""Test if new entity is created if new version is available."""
mock_get_uuid.return_value = MOCK_HUUID
mock_get_newest_version.return_value = mock_coro((MOCK_VERSION, ''))
self.assertIsNone(self.hass.states.get(updater.ENTITY_ID))
res = yield from async_setup_component(
hass, updater.DOMAIN, {updater.DOMAIN: {}})
assert res, 'Updater failed to setup'
mock_get_newest_version.return_value = (NEW_VERSION, '')
with patch('homeassistant.components.updater.CURRENT_VERSION',
MOCK_VERSION):
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(hours=1))
yield from hass.async_block_till_done()
for secs in [-1, 0, 1]:
fire_time_changed(self.hass, _dt + timedelta(seconds=secs))
self.hass.block_till_done()
assert hass.states.get(updater.ENTITY_ID) is None
self.assertTrue(self.hass.states.is_state(
updater.ENTITY_ID, NEW_VERSION))
@patch('homeassistant.components.updater.requests.post')
def test_errors_while_fetching_new_version( # pylint: disable=invalid-name
self, mock_get):
"""Test for errors while fetching the new version."""
mock_get.side_effect = requests.RequestException
uuid = '0000'
self.assertIsNone(updater.get_newest_version(uuid))
@asyncio.coroutine
@freeze_time("Mar 15th, 2017")
def test_disable_reporting(hass, mock_get_uuid, mock_get_newest_version):
"""Test if new entity is created if new version is available."""
mock_get_uuid.return_value = MOCK_HUUID
mock_get_newest_version.return_value = mock_coro((MOCK_VERSION, ''))
mock_get.side_effect = ValueError
self.assertIsNone(updater.get_newest_version(uuid))
res = yield from async_setup_component(
hass, updater.DOMAIN, {updater.DOMAIN: {
'reporting': False
}})
assert res, 'Updater failed to setup'
mock_get.side_effect = vol.Invalid('Expected dictionary')
self.assertIsNone(updater.get_newest_version(uuid))
with patch('homeassistant.components.updater.CURRENT_VERSION',
MOCK_VERSION):
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(hours=1))
yield from hass.async_block_till_done()
def test_uuid_function(self):
"""Test if the uuid function works."""
path = self.hass.config.path(updater.UPDATER_UUID_FILE)
try:
# pylint: disable=protected-access
uuid = updater._load_uuid(self.hass)
assert os.path.isfile(path)
uuid2 = updater._load_uuid(self.hass)
assert uuid == uuid2
os.remove(path)
uuid2 = updater._load_uuid(self.hass)
assert uuid != uuid2
finally:
os.remove(path)
assert hass.states.get(updater.ENTITY_ID) is None
call = mock_get_newest_version.mock_calls[0][1]
assert call[0] is hass
assert call[1] is None
@requests_mock.Mocker()
def test_reporting_false_works(self, m):
"""Test we do not send any data."""
m.post(updater.UPDATER_URL,
json={'version': '0.15',
'release-notes': 'https://home-assistant.io'})
response = updater.get_newest_version(None)
@asyncio.coroutine
def test_get_newest_version_no_analytics_when_no_huuid(hass, aioclient_mock):
"""Test we do not gather analytics when no huuid is passed in."""
aioclient_mock.post(updater.UPDATER_URL, json=MOCK_RESPONSE)
assert response == ('0.15', 'https://home-assistant.io')
with patch('homeassistant.components.updater.get_system_info',
side_effect=Exception):
res = yield from updater.get_newest_version(hass, None)
assert res == (MOCK_RESPONSE['version'],
MOCK_RESPONSE['release-notes'])
history = m.request_history
assert len(history) == 1
assert history[0].json() == {}
@asyncio.coroutine
def test_get_newest_version_analytics_when_huuid(hass, aioclient_mock):
"""Test we do not gather analytics when no huuid is passed in."""
aioclient_mock.post(updater.UPDATER_URL, json=MOCK_RESPONSE)
@patch('homeassistant.components.updater.get_newest_version')
def test_error_during_fetch_works(
self, mock_get_newest_version):
"""Test if no entity is created if same version."""
mock_get_newest_version.return_value = None
with patch('homeassistant.components.updater.get_system_info',
Mock(return_value=mock_coro({'fake': 'bla'}))):
res = yield from updater.get_newest_version(hass, MOCK_HUUID)
assert res == (MOCK_RESPONSE['version'],
MOCK_RESPONSE['release-notes'])
updater.check_newest_version(self.hass, None)
self.assertIsNone(self.hass.states.get(updater.ENTITY_ID))
@asyncio.coroutine
def test_error_fetching_new_version_timeout(hass):
"""Test we do not gather analytics when no huuid is passed in."""
with patch('homeassistant.components.updater.get_system_info',
Mock(return_value=mock_coro({'fake': 'bla'}))), \
patch('async_timeout.timeout', side_effect=asyncio.TimeoutError):
res = yield from updater.get_newest_version(hass, MOCK_HUUID)
assert res is None
@asyncio.coroutine
def test_error_fetching_new_version_bad_json(hass, aioclient_mock):
"""Test we do not gather analytics when no huuid is passed in."""
aioclient_mock.post(updater.UPDATER_URL, text='not json')
with patch('homeassistant.components.updater.get_system_info',
Mock(return_value=mock_coro({'fake': 'bla'}))):
res = yield from updater.get_newest_version(hass, MOCK_HUUID)
assert res is None
@asyncio.coroutine
def test_error_fetching_new_version_invalid_response(hass, aioclient_mock):
"""Test we do not gather analytics when no huuid is passed in."""
aioclient_mock.post(updater.UPDATER_URL, json={
'version': '0.15'
# 'release-notes' is missing
})
with patch('homeassistant.components.updater.get_system_info',
Mock(return_value=mock_coro({'fake': 'bla'}))):
res = yield from updater.get_newest_version(hass, MOCK_HUUID)
assert res is None