8000 Fix flaky updater tests by andrewsayre · Pull Request #26221 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix flaky updater tests #26221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 27, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
8000
Diff view
118 changes: 58 additions & 60 deletions tests/components/updater/test_init.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
"""The tests for the Updater component."""
import asyncio
from datetime import timedelta
from unittest.mock import patch, Mock
from unittest.mock import Mock, patch

import pytest

from homeassistant.setup import async_setup_component
from homeassistant.components import updater
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util

from tests.common import (
MockDependency,
async_fire_time_changed,
mock_coro,
mock_component,
MockDependency,
mock_coro,
)

NEW_VERSION = "10000.0"
Expand All @@ -31,44 +32,44 @@ def mock_distro():
yield


@pytest.fixture
def mock_get_newest_version():
@pytest.fixture(name="mock_get_newest_version")
def mock_get_newest_version_fixture():
"""Fixture to mock get_newest_version."""
with patch("homeassistant.components.updater.get_newest_version") as mock:
yield mock


@pytest.fixture
def mock_get_uuid():
@pytest.fixture(name="mock_get_uuid")
def mock_get_uuid_fixture():
"""Fixture to mock get_uuid."""
with patch("homeassistant.components.updater._load_uuid") as mock:
yield mock


@pytest.fixture
def mock_utcnow():
@pytest.fixture(name="mock_utcnow")
def mock_utcnow_fixture():
"""Fixture to mock utcnow."""
with patch("homeassistant.components.updater.dt_util.utcnow") as mock:
Copy link
Member Author
@andrewsayre andrewsayre Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where the root of the issue was. The tests weren't even using the fixture, probably because the patch wasn't working. I'm not sure why this didn't work (it does in other places in the tests, but none of those were in a fixture), but when debugging I could see it wasn't mocking. Changing it to the module then returning the method inside the yield fixed the issue.

yield mock
with patch("homeassistant.components.updater.dt_util") as mock:
yield mock.utcnow


@asyncio.coroutine
def test_new_version_shows_entity_startup(hass, mock_get_uuid, mock_get_newest_version):
async def test_new_version_shows_entity_startup(
hass, mock_get_uuid, mock_get_newest_version
):
"""Test if binary sensor is unavailable at first."""
mock_get_uuid.return_value = MOCK_HUUID
mock_get_newest_version.return_value = mock_coro((NEW_VERSION, RELEASE_NOTES))

res = yield from async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
res = await async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
assert res, "Updater failed to set up"

yield from hass.async_block_till_done()
await hass.async_block_till_done()
assert hass.states.is_state("binary_sensor.updater", "unavailable")
assert "newest_version" not in hass.states.get("binary_sensor.updater").attributes
assert "release_notes" not in hass.states.get("binary_sensor.updater").attributes


@asyncio.coroutine
def test_rename_entity(hass, mock_get_uuid, mock_get_newest_version):
async def test_rename_entity(hass, mock_get_uuid, mock_get_newest_version, mock_utcnow):
"""Test if renaming the binary sensor works correctly."""
mock_get_uuid.return_value = MOCK_HUUID
mock_get_newest_version.return_value = mock_coro((NEW_VERSION, RELEASE_NOTES))
Expand All @@ -77,32 +78,33 @@ def test_rename_entity(hass, mock_get_uuid, mock_get_newest_version):
later = now + timedelta(hours=1)
mock_utcnow.return_value = now

res = yield from async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
res = await async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
assert res, "Updater failed to set up"

yield from hass.async_block_till_done()
await hass.async_block_till_done()
assert hass.states.is_state("binary_sensor.updater", "unavailable")
assert hass.states.get("binary_sensor.new_entity_id") is None

entity_registry = yield from hass.helpers.entity_registry.async_get_registry()
entity_registry = await hass.helpers.entity_registry.async_get_registry()
entity_registry.async_update_entity(
"binary_sensor.updater", new_entity_id="binary_sensor.new_entity_id"
)

yield from hass.async_block_till_done()
await hass.async_block_till_done()
assert hass.states.is_state("binary_sensor.new_entity_id", "unavailable")
assert hass.states.get("binary_sensor.updater") is None

with patch("homeassistant.components.updater.current_version", MOCK_VERSION):
async_fire_time_changed(hass, later)
yield from hass.async_block_till_done()
await hass.async_block_till_done()

assert hass.states.is_state("binary_sensor.new_entity_id", "on")
assert hass.states.get("binary_sensor.updater") is None


@asyncio.coroutine
def test_new_version_shows_entity_true(hass, mock_get_uuid, mock_get_newest_version):
async def test_new_version_shows_entity_true(
hass, mock_get_uuid, mock_get_newest_version, mock_utcnow
):
"""Test if sensor is true if new version is available."""
mock_get_uuid.return_value = MOCK_HUUID
mock_get_newest_version.return_value = mock_coro((NEW_VERSION, RELEASE_NOTES))
Expand All @@ -111,13 +113,13 @@ def test_new_version_shows_entity_true(hass, mock_get_uuid, mock_get_newest_vers
later = now + timedelta(hours=1)
mock_utcnow.return_value = now

res = yield from async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
res = await async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
assert res, "Updater failed to set up"

yield from hass.async_block_till_done()
await hass.async_block_till_done()
with patch("homeassistant.components.updater.current_version", MOCK_VERSION):
async_fire_time_changed(hass, later)
yield from hass.async_block_till_done()
await hass.async_block_till_done()

assert hass.states.is_state("binary_sensor.updater", "on")
assert (
Expand All @@ -130,8 +132,9 @@ def test_new_version_shows_entity_true(hass, mock_get_uuid, mock_get_newest_vers
)


@asyncio.coroutine
def test_same_version_shows_entity_false(hass, mock_get_uuid, mock_get_newest_version):
async def test_same_version_shows_entity_false(
hass, mock_get_uuid, mock_get_newest_version, mock_utcnow
):
"""Test if sensor is false if no new version is available."""
mock_get_uuid.return_value = MOCK_HUUID
mock_get_newest_version.return_value = mock_coro((MOCK_VERSION, ""))
Expand All @@ -140,13 +143,13 @@ def test_same_version_shows_entity_false(hass, mock_get_uuid, mock_get_newest_ve
later = now + timedelta(hours=1)
mock_utcnow.return_value = now

res = yield from async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
res = await async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
assert res, "Updater failed to set up"

yield from hass.async_block_till_done()
await hass.async_block_till_done()
with patch("homeassistant.components.updater.current_version", MOCK_VERSION):
async_fire_time_changed(hass, later)
yield from hass.async_block_till_done()
await hass.async_block_till_done()

assert hass.states.is_state("binary_sensor.updater", "off")
assert (
Expand All @@ -156,8 +159,9 @@ def test_same_version_shows_entity_false(hass, mock_get_uuid, mock_get_newest_ve
assert "release_notes" not in hass.states.get("binary_sensor.updater").attributes


@asyncio.coroutine
def test_disable_reporting(hass, mock_get_uuid, mock_get_newest_version):
async def test_disable_reporting(
hass, mock_get_uuid, mock_get_newest_version, mock_utcnow
):
"""Test we do not gather analytics when disable reporting is active."""
mock_get_uuid.return_value = MOCK_HUUID
mock_get_newest_version.return_value = mock_coro((MOCK_VERSION, ""))
Expand All @@ -166,74 +170,69 @@ def test_disable_reporting(hass, mock_get_uuid, mock_get_newest_version):
later = now + timedelta(hours=1)
mock_utcnow.return_value = now

res = yield from async_setup_component(
res = await async_setup_component(
hass, updater.DOMAIN, {updater.DOMAIN: {"reporting": False}}
)
assert res, "Updater failed to set up"

yield from hass.async_block_till_done()
await hass.async_block_till_done()
with patch("homeassistant.components.updater.current_version", MOCK_VERSION):
async_fire_time_changed(hass, later)
yield from hass.async_block_till_done()
await hass.async_block_till_done()

assert hass.states.is_state("binary_sensor.updater", "off")
res = yield from updater.get_newest_version(hass, MOCK_HUUID, MOCK_CONFIG)
res = await updater.get_newest_version(hass, MOCK_HUUID, MOCK_CONFIG)
call = mock_get_newest_version.mock_calls[0][1]
assert call[0] is hass
assert call[1] is None


@asyncio.coroutine
def test_get_newest_version_no_analytics_when_no_huuid(hass, aioclient_mock):
async 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)

with patch(
"homeassistant.helpers.system_info.async_get_system_info", side_effect=Exception
):
res = yield from updater.get_newest_version(hass, None, False)
res = await updater.get_newest_version(hass, None, False)
assert res == (MOCK_RESPONSE["version"], MOCK_RESPONSE["release-notes"])


@asyncio.coroutine
def test_get_newest_version_analytics_when_huuid(hass, aioclient_mock):
async def test_get_newest_version_analytics_when_huuid(hass, aioclient_mock):
"""Test we gather analytics when huuid is passed in."""
aioclient_mock.post(updater.UPDATER_URL, json=MOCK_RESPONSE)

with patch(
"homeassistant.helpers.system_info.async_get_system_info",
Mock(return_value=mock_coro({"fake": "bla"})),
):
res = yield from updater.get_newest_version(hass, MOCK_HUUID, False)
res = await updater.get_newest_version(hass, MOCK_HUUID, False)
assert res == (MOCK_RESPONSE["version"], MOCK_RESPONSE["release-notes"])


@asyncio.coroutine
def test_error_fetching_new_version_timeout(hass):
async def test_error_fetching_new_version_timeout(hass):
"""Test we handle timeout error while fetching new version."""
with patch(
"homeassistant.helpers.system_info.async_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, False)
res = await updater.get_newest_version(hass, MOCK_HUUID, False)
assert res is None


@asyncio.coroutine
def test_error_fetching_new_version_bad_json(hass, aioclient_mock):
async def test_error_fetching_new_version_bad_json(hass, aioclient_mock):
"""Test we handle json error while fetching new version."""
aioclient_mock.post(updater.UPDATER_URL, text="not json")

with patch(
"homeassistant.helpers.system_info.async_get_system_info",
Mock(return_value=mock_coro({"fake": "bla"})),
):
res = yield from updater.get_newest_version(hass, MOCK_HUUID, False)
res = await updater.get_newest_version(hass, MOCK_HUUID, False)
assert res is None


@asyncio.coroutine
def test_error_fetching_new_version_invalid_response(hass, aioclient_mock):
async def test_error_fetching_new_version_invalid_response(hass, aioclient_mock):
"""Test we handle response error while fetching new version."""
aioclient_mock.post(
updater.UPDATER_URL,
Expand All @@ -247,13 +246,12 @@ def test_error_fetching_new_version_invalid_response(hass, aioclient_mock):
"homeassistant.helpers.system_info.async_get_system_info",
Mock(return_value=mock_coro({"fake": "bla"})),
):
res = yield from updater.get_newest_version(hass, MOCK_HUUID, False)
res = await updater.get_newest_version(hass, MOCK_HUUID, False)
assert res is None


@asyncio.coroutine
def test_new_version_shows_entity_after_hour_hassio(
hass, mock_get_uuid, mock_get_newest_version
async def test_new_version_shows_entity_after_hour_hassio(
hass, mock_get_uuid, mock_get_newest_version, mock_utcnow
):
"""Test if binary sensor gets updated if new version is available / hass.io."""
mock_get_uuid.return_value = MOCK_HUUID
Expand All @@ -265,13 +263,13 @@ def test_new_version_shows_entity_after_hour_hassio(
later = now + timedelta(hours=1)
mock_utcnow.return_value = now

res = yield from async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
res = await async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
assert res, "Updater failed to set up"

yield from hass.async_block_till_done()
await hass.async_block_till_done()
with patch("homeassistant.components.updater.current_version", MOCK_VERSION):
async_fire_time_changed(hass, later)
yield from hass.async_block_till_done()
await hass.async_block_till_done()

assert hass.states.is_state("binary_sensor.updater", "on")
assert (
Expand Down
0