mirror of
https://github.com/home-assistant/core
synced 2024-08-31 05:57:13 +02:00
Use dev endpoint for dev installations (#49597)
This commit is contained in:
parent
8013eb0e08
commit
019484f148
@ -18,6 +18,7 @@ from homeassistant.setup import async_get_loaded_integrations
|
|||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ANALYTICS_ENDPOINT_URL,
|
ANALYTICS_ENDPOINT_URL,
|
||||||
|
ANALYTICS_ENDPOINT_URL_DEV,
|
||||||
ATTR_ADDON_COUNT,
|
ATTR_ADDON_COUNT,
|
||||||
ATTR_ADDONS,
|
ATTR_ADDONS,
|
||||||
ATTR_AUTO_UPDATE,
|
ATTR_AUTO_UPDATE,
|
||||||
@ -78,6 +79,14 @@ class Analytics:
|
|||||||
"""Return the uuid for the analytics integration."""
|
"""Return the uuid for the analytics integration."""
|
||||||
return self._data[ATTR_UUID]
|
return self._data[ATTR_UUID]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def endpoint(self) -> str:
|
||||||
|
"""Return the endpoint that will receive the payload."""
|
||||||
|
if HA_VERSION.endswith("0.dev0"):
|
||||||
|
# dev installations will contact the dev analytics environment
|
||||||
|
return ANALYTICS_ENDPOINT_URL_DEV
|
||||||
|
return ANALYTICS_ENDPOINT_URL
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supervisor(self) -> bool:
|
def supervisor(self) -> bool:
|
||||||
"""Return bool if a supervisor is present."""
|
"""Return bool if a supervisor is present."""
|
||||||
@ -219,7 +228,7 @@ class Analytics:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
with async_timeout.timeout(30):
|
with async_timeout.timeout(30):
|
||||||
response = await self.session.post(ANALYTICS_ENDPOINT_URL, json=payload)
|
response = await self.session.post(self.endpoint, json=payload)
|
||||||
if response.status == 200:
|
if response.status == 200:
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
(
|
(
|
||||||
@ -230,7 +239,9 @@ class Analytics:
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
LOGGER.warning(
|
LOGGER.warning(
|
||||||
"Sending analytics failed with statuscode %s", response.status
|
"Sending analytics failed with statuscode %s from %s",
|
||||||
|
response.status,
|
||||||
|
self.endpoint,
|
||||||
)
|
)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
LOGGER.error("Timeout sending analytics to %s", ANALYTICS_ENDPOINT_URL)
|
LOGGER.error("Timeout sending analytics to %s", ANALYTICS_ENDPOINT_URL)
|
||||||
|
@ -5,6 +5,7 @@ import logging
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
ANALYTICS_ENDPOINT_URL = "https://analytics-api.home-assistant.io/v1"
|
ANALYTICS_ENDPOINT_URL = "https://analytics-api.home-assistant.io/v1"
|
||||||
|
ANALYTICS_ENDPOINT_URL_DEV = "https://analytics-api-dev.home-assistant.io/v1"
|
||||||
DOMAIN = "analytics"
|
DOMAIN = "analytics"
|
||||||
INTERVAL = timedelta(days=1)
|
INTERVAL = timedelta(days=1)
|
||||||
STORAGE_KEY = "core.analytics"
|
STORAGE_KEY = "core.analytics"
|
||||||
|
@ -7,6 +7,7 @@ import pytest
|
|||||||
from homeassistant.components.analytics.analytics import Analytics
|
from homeassistant.components.analytics.analytics import Analytics
|
||||||
from homeassistant.components.analytics.const import (
|
from homeassistant.components.analytics.const import (
|
||||||
ANALYTICS_ENDPOINT_URL,
|
ANALYTICS_ENDPOINT_URL,
|
||||||
|
ANALYTICS_ENDPOINT_URL_DEV,
|
||||||
ATTR_BASE,
|
ATTR_BASE,
|
||||||
ATTR_DIAGNOSTICS,
|
ATTR_DIAGNOSTICS,
|
||||||
ATTR_PREFERENCES,
|
ATTR_PREFERENCES,
|
||||||
@ -14,16 +15,18 @@ from homeassistant.components.analytics.const import (
|
|||||||
ATTR_USAGE,
|
ATTR_USAGE,
|
||||||
)
|
)
|
||||||
from homeassistant.components.api import ATTR_UUID
|
from homeassistant.components.api import ATTR_UUID
|
||||||
from homeassistant.const import ATTR_DOMAIN, __version__ as HA_VERSION
|
from homeassistant.const import ATTR_DOMAIN
|
||||||
from homeassistant.loader import IntegrationNotFound
|
from homeassistant.loader import IntegrationNotFound
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
MOCK_UUID = "abcdefg"
|
MOCK_UUID = "abcdefg"
|
||||||
|
MOCK_VERSION = "1970.1.0"
|
||||||
|
MOCK_VERSION_DEV = "1970.1.0.dev0"
|
||||||
|
MOCK_VERSION_NIGHTLY = "1970.1.0.dev19700101"
|
||||||
|
|
||||||
|
|
||||||
async def test_no_send(hass, caplog, aioclient_mock):
|
async def test_no_send(hass, caplog, aioclient_mock):
|
||||||
"""Test send when no prefrences are defined."""
|
"""Test send when no prefrences are defined."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
|
||||||
analytics = Analytics(hass)
|
analytics = Analytics(hass)
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.hassio.is_hassio",
|
"homeassistant.components.hassio.is_hassio",
|
||||||
@ -77,8 +80,13 @@ async def test_failed_to_send(hass, caplog, aioclient_mock):
|
|||||||
analytics = Analytics(hass)
|
analytics = Analytics(hass)
|
||||||
await analytics.save_preferences({ATTR_BASE: True})
|
await analytics.save_preferences({ATTR_BASE: True})
|
||||||
assert analytics.preferences[ATTR_BASE]
|
assert analytics.preferences[ATTR_BASE]
|
||||||
await analytics.send_analytics()
|
|
||||||
assert "Sending analytics failed with statuscode 400" in caplog.text
|
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
assert (
|
||||||
|
f"Sending analytics failed with statuscode 400 from {ANALYTICS_ENDPOINT_URL}"
|
||||||
|
in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_failed_to_send_raises(hass, caplog, aioclient_mock):
|
async def test_failed_to_send_raises(hass, caplog, aioclient_mock):
|
||||||
@ -87,7 +95,9 @@ async def test_failed_to_send_raises(hass, caplog, aioclient_mock):
|
|||||||
analytics = Analytics(hass)
|
analytics = Analytics(hass)
|
||||||
await analytics.save_preferences({ATTR_BASE: True})
|
await analytics.save_preferences({ATTR_BASE: True})
|
||||||
assert analytics.preferences[ATTR_BASE]
|
assert analytics.preferences[ATTR_BASE]
|
||||||
await analytics.send_analytics()
|
|
||||||
|
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
|
await analytics.send_analytics()
|
||||||
assert "Error sending analytics" in caplog.text
|
assert "Error sending analytics" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
@ -99,12 +109,14 @@ async def test_send_base(hass, caplog, aioclient_mock):
|
|||||||
await analytics.save_preferences({ATTR_BASE: True})
|
await analytics.save_preferences({ATTR_BASE: True})
|
||||||
assert analytics.preferences[ATTR_BASE]
|
assert analytics.preferences[ATTR_BASE]
|
||||||
|
|
||||||
with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex:
|
with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex, patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
|
):
|
||||||
hex.return_value = MOCK_UUID
|
hex.return_value = MOCK_UUID
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
|
|
||||||
assert f"'uuid': '{MOCK_UUID}'" in caplog.text
|
assert f"'uuid': '{MOCK_UUID}'" in caplog.text
|
||||||
assert f"'version': '{HA_VERSION}'" in caplog.text
|
assert f"'version': '{MOCK_VERSION}'" in caplog.text
|
||||||
assert "'installation_type':" in caplog.text
|
assert "'installation_type':" in caplog.text
|
||||||
assert "'integration_count':" not in caplog.text
|
assert "'integration_count':" not in caplog.text
|
||||||
assert "'integrations':" not in caplog.text
|
assert "'integrations':" not in caplog.text
|
||||||
@ -132,14 +144,16 @@ async def test_send_base_with_supervisor(hass, caplog, aioclient_mock):
|
|||||||
side_effect=Mock(return_value=True),
|
side_effect=Mock(return_value=True),
|
||||||
), patch(
|
), patch(
|
||||||
"uuid.UUID.hex", new_callable=PropertyMock
|
"uuid.UUID.hex", new_callable=PropertyMock
|
||||||
) as hex:
|
) as hex, patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
|
):
|
||||||
hex.return_value = MOCK_UUID
|
hex.return_value = MOCK_UUID
|
||||||
await analytics.load()
|
await analytics.load()
|
||||||
|
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
|
|
||||||
assert f"'uuid': '{MOCK_UUID}'" in caplog.text
|
assert f"'uuid': '{MOCK_UUID}'" in caplog.text
|
||||||
assert f"'version': '{HA_VERSION}'" in caplog.text
|
assert f"'version': '{MOCK_VERSION}'" in caplog.text
|
||||||
assert "'supervisor': {'healthy': True, 'supported': True}}" in caplog.text
|
assert "'supervisor': {'healthy': True, 'supported': True}}" in caplog.text
|
||||||
assert "'installation_type':" in caplog.text
|
assert "'installation_type':" in caplog.text
|
||||||
assert "'integration_count':" not in caplog.text
|
assert "'integration_count':" not in caplog.text
|
||||||
@ -156,7 +170,8 @@ async def test_send_usage(hass, caplog, aioclient_mock):
|
|||||||
assert analytics.preferences[ATTR_USAGE]
|
assert analytics.preferences[ATTR_USAGE]
|
||||||
hass.config.components = ["default_config"]
|
hass.config.components = ["default_config"]
|
||||||
|
|
||||||
await analytics.send_analytics()
|
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
assert "'integrations': ['default_config']" in caplog.text
|
assert "'integrations': ['default_config']" in caplog.text
|
||||||
assert "'integration_count':" not in caplog.text
|
assert "'integration_count':" not in caplog.text
|
||||||
@ -200,6 +215,8 @@ async def test_send_usage_with_supervisor(hass, caplog, aioclient_mock):
|
|||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.hassio.is_hassio",
|
"homeassistant.components.hassio.is_hassio",
|
||||||
side_effect=Mock(return_value=True),
|
side_effect=Mock(return_value=True),
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
):
|
):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
assert (
|
assert (
|
||||||
@ -218,7 +235,8 @@ async def test_send_statistics(hass, caplog, aioclient_mock):
|
|||||||
assert analytics.preferences[ATTR_STATISTICS]
|
assert analytics.preferences[ATTR_STATISTICS]
|
||||||
hass.config.components = ["default_config"]
|
hass.config.components = ["default_config"]
|
||||||
|
|
||||||
await analytics.send_analytics()
|
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
|
await analytics.send_analytics()
|
||||||
assert (
|
assert (
|
||||||
"'state_count': 0, 'automation_count': 0, 'integration_count': 1, 'user_count': 0"
|
"'state_count': 0, 'automation_count': 0, 'integration_count': 1, 'user_count': 0"
|
||||||
in caplog.text
|
in caplog.text
|
||||||
@ -238,7 +256,7 @@ async def test_send_statistics_one_integration_fails(hass, caplog, aioclient_moc
|
|||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.analytics.analytics.async_get_integration",
|
"homeassistant.components.analytics.analytics.async_get_integration",
|
||||||
side_effect=IntegrationNotFound("any"),
|
side_effect=IntegrationNotFound("any"),
|
||||||
):
|
), patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
|
|
||||||
post_call = aioclient_mock.mock_calls[0]
|
post_call = aioclient_mock.mock_calls[0]
|
||||||
@ -260,7 +278,7 @@ async def test_send_statistics_async_get_integration_unknown_exception(
|
|||||||
with pytest.raises(ValueError), patch(
|
with pytest.raises(ValueError), patch(
|
||||||
"homeassistant.components.analytics.analytics.async_get_integration",
|
"homeassistant.components.analytics.analytics.async_get_integration",
|
||||||
side_effect=ValueError,
|
side_effect=ValueError,
|
||||||
):
|
), patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
|
||||||
@ -300,6 +318,8 @@ async def test_send_statistics_with_supervisor(hass, caplog, aioclient_mock):
|
|||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.hassio.is_hassio",
|
"homeassistant.components.hassio.is_hassio",
|
||||||
side_effect=Mock(return_value=True),
|
side_effect=Mock(return_value=True),
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
):
|
):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
assert "'addon_count': 1" in caplog.text
|
assert "'addon_count': 1" in caplog.text
|
||||||
@ -314,7 +334,9 @@ async def test_reusing_uuid(hass, aioclient_mock):
|
|||||||
|
|
||||||
await analytics.save_preferences({ATTR_BASE: True})
|
await analytics.save_preferences({ATTR_BASE: True})
|
||||||
|
|
||||||
with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex:
|
with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex, patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
|
):
|
||||||
# This is not actually called but that in itself prove the test
|
# This is not actually called but that in itself prove the test
|
||||||
hex.return_value = MOCK_UUID
|
hex.return_value = MOCK_UUID
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
@ -329,7 +351,59 @@ async def test_custom_integrations(hass, aioclient_mock):
|
|||||||
assert await async_setup_component(hass, "test_package", {"test_package": {}})
|
assert await async_setup_component(hass, "test_package", {"test_package": {}})
|
||||||
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
||||||
|
|
||||||
await analytics.send_analytics()
|
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
payload = aioclient_mock.mock_calls[0][2]
|
payload = aioclient_mock.mock_calls[0][2]
|
||||||
assert payload["custom_integrations"][0][ATTR_DOMAIN] == "test_package"
|
assert payload["custom_integrations"][0][ATTR_DOMAIN] == "test_package"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_dev_url(hass, aioclient_mock):
|
||||||
|
"""Test sending payload to dev url."""
|
||||||
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL_DEV, status=200)
|
||||||
|
analytics = Analytics(hass)
|
||||||
|
await analytics.save_preferences({ATTR_BASE: True})
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION_DEV
|
||||||
|
):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
payload = aioclient_mock.mock_calls[0]
|
||||||
|
assert str(payload[1]) == ANALYTICS_ENDPOINT_URL_DEV
|
||||||
|
|
||||||
|
|
||||||
|
async def test_dev_url_error(hass, aioclient_mock, caplog):
|
||||||
|
"""Test sending payload to dev url that returns error."""
|
||||||
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL_DEV, status=400)
|
||||||
|
analytics = Analytics(hass)
|
||||||
|
await analytics.save_preferences({ATTR_BASE: True})
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION_DEV
|
||||||
|
):
|
||||||
|
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
payload = aioclient_mock.mock_calls[0]
|
||||||
|
assert str(payload[1]) == ANALYTICS_ENDPOINT_URL_DEV
|
||||||
|
assert (
|
||||||
|
f"Sending analytics failed with statuscode 400 from {ANALYTICS_ENDPOINT_URL_DEV}"
|
||||||
|
in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_nightly_endpoint(hass, aioclient_mock):
|
||||||
|
"""Test sending payload to production url when running nightly."""
|
||||||
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
|
analytics = Analytics(hass)
|
||||||
|
await analytics.save_preferences({ATTR_BASE: True})
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION_NIGHTLY
|
||||||
|
):
|
||||||
|
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
payload = aioclient_mock.mock_calls[0]
|
||||||
|
assert str(payload[1]) == ANALYTICS_ENDPOINT_URL
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
"""The tests for the analytics ."""
|
"""The tests for the analytics ."""
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from homeassistant.components.analytics.const import ANALYTICS_ENDPOINT_URL, DOMAIN
|
from homeassistant.components.analytics.const import ANALYTICS_ENDPOINT_URL, DOMAIN
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
MOCK_VERSION = "1970.1.0"
|
||||||
|
|
||||||
|
|
||||||
async def test_setup(hass):
|
async def test_setup(hass):
|
||||||
"""Test setup of the integration."""
|
"""Test setup of the integration."""
|
||||||
@ -24,10 +28,11 @@ async def test_websocket(hass, hass_ws_client, aioclient_mock):
|
|||||||
|
|
||||||
assert response["success"]
|
assert response["success"]
|
||||||
|
|
||||||
await ws_client.send_json(
|
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
{"id": 2, "type": "analytics/preferences", "preferences": {"base": True}}
|
await ws_client.send_json(
|
||||||
)
|
{"id": 2, "type": "analytics/preferences", "preferences": {"base": True}}
|
||||||
response = await ws_client.receive_json()
|
)
|
||||||
|
response = await ws_client.receive_json()
|
||||||
assert len(aioclient_mock.mock_calls) == 1
|
assert len(aioclient_mock.mock_calls) == 1
|
||||||
assert response["result"]["preferences"]["base"]
|
assert response["result"]["preferences"]["base"]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user