8000 Remove analytics from updater by ludeeus · Pull Request #48518 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Remove analytics from updater #48518

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 2 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
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
Diff view
66 changes: 21 additions & 45 deletions homeassistant/components/updater/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import async_timeout
from awesomeversion import AwesomeVersion
from distro import linux_distribution
import voluptuous as vol

from homeassistant.const import __version__ as current_version
Expand All @@ -23,20 +22,22 @@

DOMAIN = "updater"

UPDATER_URL = "https://updater.home-assistant.io/"
UPDATER_URL = "https://www.home-assistant.io/version.json"


CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: {
vol.Optional(CONF_REPORTING, default=True): cv.boolean,
vol.Optional(CONF_COMPONENT_REPORTING, default=False): cv.boolean,
vol.Optional(CONF_REPORTING): cv.boolean,
vol.Optional(CONF_COMPONENT_REPORTING): cv.boolean,
}
},
extra=vol.ALLOW_EXTRA,
)

RESPONSE_SCHEMA = vol.Schema(
{vol.Required("version"): cv.string, vol.Required("release-notes"): cv.url}
{vol.Required("current_version"): cv.string, vol.Required("release_notes"): cv.url},
extra=vol.REMOVE_EXTRA,
)


Expand All @@ -52,30 +53,27 @@ def __init__(self, update_available: bool, newest_version: str, release_notes: s

async def async_setup(hass, config):
"""Set up the updater component."""
if "dev" in current_version:
# This component only makes sense in release versions
_LOGGER.info("Running on 'dev', only analytics will be submitted")

conf = config.get(DOMAIN, {})
if conf.get(CONF_REPORTING):
huuid = await hass.helpers.instance_id.async_get()
else:
huuid = None

include_components = conf.get(CONF_COMPONENT_REPORTING)
for option in (CONF_COMPONENT_REPORTING, CONF_REPORTING):
if option in conf:
_LOGGER.warning(
"Analytics reporting with the option '%s' "
"is deprecated and you should remove that from your configuration. "
"The analytics part of this integration has moved to the new 'analytics' integration",
option,
)
Comment on lines +58 to +65
Copy link
Member
@frenck frenck Mar 30, 2021

Choose a reason for hiding this comment

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

Why not use cv.deprecated in the config schema?

Copy link
Member Author

Choose a reason for hiding this comment

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

I want to mention the key, and does not care about it's value

Copy link
Member

Choose a reason for hiding this comment

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

cv.deprecated mentions the key and doesn't care about it's value?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right... I was thinking of something else!
The response for cv.deprecated == I want to guide them to the analytics integration.

Copy link
Member
10000

Choose a reason for hiding this comment

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

Oh right, these users won't have the default_config 👍


async def check_new_version() -> Updater:
"""Check if a new version is available and report if one is."""
newest, release_notes = await get_newest_version(
hass, huuid, include_components
)

_LOGGER.debug("Fetched version %s: %s", newest, release_notes)

# Skip on dev
if "dev" in current_version:
return Updater(False, "", "")

newest, release_notes = await get_newest_version(hass)

_LOGGER.debug("Fetched version %s: %s", newest, release_notes)

# Load data from Supervisor
if hass.components.hassio.is_hassio():
core_info = hass.components.hassio.get_core_info()
Expand Down Expand Up @@ -121,34 +119,12 @@ async def check_new_version() -> Updater:
return True


async def get_newest_version(hass, huuid, include_components):
async def get_newest_version(hass):
"""Get the newest Home Assistant version."""
if huuid:
info_object = await hass.helpers.system_info.async_get_system_info()

if include_components:
info_object["components"] = list(hass.config.components)

linux_dist = await hass.async_add_executor_job(linux_distribution, False)
info_object["distribution"] = linux_dist[0]
info_object["os_version"] = linux_dist[1]

info_object["huuid"] = huuid
else:
info_object = {}

session = async_get_clientsession(hass)

with async_timeout.timeout(30):
req = await session.post(UPDATER_URL, json=info_object)

_LOGGER.info(
(
"Submitted analytics to Home Assistant servers. "
"Information submitted includes %s"
),
info_object,
)
req = await session.get(UPDATER_URL)

try:
res = await req.json()
Expand All @@ -159,7 +135,7 @@ async def get_newest_version(hass, huuid, include_components):

try:
res = RESPONSE_SCHEMA(res)
return res["version"], res["release-notes"]
return res["current_version"], res["release_notes"]
except vol.Invalid as err:
raise update_coordinator.UpdateFailed(
f"Got unexpected response: {err}"
Expand Down
71 changes: 15 additions & 56 deletions tests/components/updater/test_init.py
6DB6
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""The tests for the Updater component."""
"""The tests for the Updater integration."""
from unittest.mock import patch

import pytest
Expand All @@ -12,8 +12,10 @@
NEW_VERSION = "10000.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"}
MOCK_RESPONSE = {
"current_version": "0.15",
"release_notes": "https://home-assistant.io",
}
MOCK_CONFIG = {updater.DOMAIN: {"reporting": True}}
RELEASE_NOTES = "test release notes"

Expand All @@ -35,19 +37,8 @@ def mock_get_newest_version_fixture():
yield mock


@pytest.fixture(name="mock_get_uuid", autouse=True)
def mock_get_uuid_fixture():
"""Fixture to mock get_uuid."""
with patch("homeassistant.helpers.instance_id.async_get") as mock:
yield mock


async 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_newest_version):
"""Test if sensor is true if new version is available."""
mock_get_uuid.return_value = MOCK_HUUID

assert await async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})

await hass.async_block_till_done()
Expand All @@ -62,11 +53,8 @@ async def test_new_version_shows_entity_true(
)


async 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_newest_version):
"""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_VERSION, "")

assert await async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
Expand All @@ -81,60 +69,32 @@ async def test_same_version_shows_entity_false(
assert "release_notes" not in hass.states.get("binary_sensor.updater").attributes


async def test_disable_reporting(hass, mock_get_uuid, mock_get_newest_version):
async def test_deprecated_reporting(hass, mock_get_newest_version, caplog):
"""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_VERSION, "")

assert await async_setup_component(
hass, updater.DOMAIN, {updater.DOMAIN: {"reporting": False}}
hass, updater.DOMAIN, {updater.DOMAIN: {"reporting": True}}
)
await hass.async_block_till_done()

assert hass.states.is_state("binary_sensor.updater", "off")
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


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 = await updater.get_newest_version(hass, None, False)
assert res == (MOCK_RESPONSE["version"], MOCK_RESPONSE["release-notes"])


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",
return_value={"fake": "bla"},
):
res = await updater.get_newest_version(hass, MOCK_HUUID, False)
assert res == (MOCK_RESPONSE["version"], MOCK_RESPONSE["release-notes"])
assert "deprecated" in caplog.text


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")
aioclient_mock.get(updater.UPDATER_URL, text="not json")

with patch(
"homeassistant.helpers.system_info.async_get_system_info",
return_value={"fake": "bla"},
), pytest.raises(UpdateFailed):
await updater.get_newest_version(hass, MOCK_HUUID, False)
await updater.get_newest_version(hass)


async def test_error_fetching_new_version_invalid_response(hass, aioclient_mock):
"""Test we handle response error while fetching new version."""
aioclient_mock.post(
aioclient_mock.get(
updater.UPDATER_URL,
json={
"version": "0.15"
Expand All @@ -146,14 +106,13 @@ async def test_error_fetching_new_version_invalid_response(hass, aioclient_mock)
"homeassistant.helpers.system_info.async_get_system_info",
return_value={"fake": "bla"},
), pytest.raises(UpdateFailed):
await updater.get_newest_version(hass, MOCK_HUUID, False)
await updater.get_newest_version(hass)


async def test_new_version_shows_entity_after_hour_hassio(
hass, mock_get_uuid, mock_get_newest_version
hass, mock_get_newest_version
):
"""Test if binary sensor gets updated if new version is available / Hass.io."""
mock_get_uuid.return_value = MOCK_HUUID
mock_component(hass, "hassio")
hass.data["hassio_core_info"] = {"version_latest": "999.0"}

Expand Down
0