core/tests/components/nextdns/test_sensor.py

572 lines
20 KiB
Python

"""Test sensor of NextDNS integration."""
from datetime import timedelta
from unittest.mock import patch
from nextdns import ApiError
from homeassistant.components.nextdns.const import DOMAIN
from homeassistant.components.sensor import (
ATTR_STATE_CLASS,
DOMAIN as SENSOR_DOMAIN,
SensorStateClass,
)
from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT, PERCENTAGE, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util.dt import utcnow
from . import DNSSEC, ENCRYPTION, IP_VERSIONS, PROTOCOLS, STATUS, init_integration
from tests.common import async_fire_time_changed
async def test_sensor(hass: HomeAssistant) -> None:
"""Test states of sensors."""
registry = er.async_get(hass)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_doh_queries",
suggested_object_id="fake_profile_dns_over_https_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_doh3_queries",
suggested_object_id="fake_profile_dns_over_http_3_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_doh_queries_ratio",
suggested_object_id="fake_profile_dns_over_https_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_doh3_queries_ratio",
suggested_object_id="fake_profile_dns_over_http_3_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_doq_queries",
suggested_object_id="fake_profile_dns_over_quic_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_doq_queries_ratio",
suggested_object_id="fake_profile_dns_over_quic_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_dot_queries",
suggested_object_id="fake_profile_dns_over_tls_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_dot_queries_ratio",
suggested_object_id="fake_profile_dns_over_tls_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_not_validated_queries",
suggested_object_id="fake_profile_dnssec_not_validated_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_validated_queries",
suggested_object_id="fake_profile_dnssec_validated_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_validated_queries_ratio",
suggested_object_id="fake_profile_dnssec_validated_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_encrypted_queries",
suggested_object_id="fake_profile_encrypted_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_encrypted_queries_ratio",
suggested_object_id="fake_profile_encrypted_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_ipv4_queries",
suggested_object_id="fake_profile_ipv4_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_ipv6_queries",
suggested_object_id="fake_profile_ipv6_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_ipv6_queries_ratio",
suggested_object_id="fake_profile_ipv6_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_tcp_queries",
suggested_object_id="fake_profile_tcp_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_tcp_queries_ratio",
suggested_object_id="fake_profile_tcp_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_udp_queries",
suggested_object_id="fake_profile_udp_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_udp_queries_ratio",
suggested_object_id="fake_profile_udp_queries_ratio",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_unencrypted_queries",
suggested_object_id="fake_profile_unencrypted_queries",
disabled_by=None,
)
await init_integration(hass)
state = hass.states.get("sensor.fake_profile_dns_queries")
assert state
assert state.state == "100"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dns_queries")
assert entry
assert entry.unique_id == "xyz12_all_queries"
state = hass.states.get("sensor.fake_profile_dns_queries_blocked")
assert state
assert state.state == "20"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dns_queries_blocked")
assert entry
assert entry.unique_id == "xyz12_blocked_queries"
state = hass.states.get("sensor.fake_profile_dns_queries_blocked_ratio")
assert state
assert state.state == "20.0"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_dns_queries_blocked_ratio")
assert entry
assert entry.unique_id == "xyz12_blocked_queries_ratio"
state = hass.states.get("sensor.fake_profile_dns_queries_relayed")
assert state
assert state.state == "10"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dns_queries_relayed")
assert entry
assert entry.unique_id == "xyz12_relayed_queries"
state = hass.states.get("sensor.fake_profile_dns_over_https_queries")
assert state
assert state.state == "20"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dns_over_https_queries")
assert entry
assert entry.unique_id == "xyz12_doh_queries"
state = hass.states.get("sensor.fake_profile_dns_over_https_queries_ratio")
assert state
assert state.state == "17.4"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_dns_over_https_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_doh_queries_ratio"
state = hass.states.get("sensor.fake_profile_dns_over_http_3_queries")
assert state
assert state.state == "15"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dns_over_http_3_queries")
assert entry
assert entry.unique_id == "xyz12_doh3_queries"
state = hass.states.get("sensor.fake_profile_dns_over_http_3_queries_ratio")
assert state
assert state.state == "13.0"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_dns_over_http_3_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_doh3_queries_ratio"
state = hass.states.get("sensor.fake_profile_dns_over_quic_queries")
assert state
assert state.state == "10"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dns_over_quic_queries")
assert entry
assert entry.unique_id == "xyz12_doq_queries"
state = hass.states.get("sensor.fake_profile_dns_over_quic_queries_ratio")
assert state
assert state.state == "8.7"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_dns_over_quic_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_doq_queries_ratio"
state = hass.states.get("sensor.fake_profile_dns_over_tls_queries")
assert state
assert state.state == "30"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dns_over_tls_queries")
assert entry
assert entry.unique_id == "xyz12_dot_queries"
state = hass.states.get("sensor.fake_profile_dns_over_tls_queries_ratio")
assert state
assert state.state == "26.1"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_dns_over_tls_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_dot_queries_ratio"
state = hass.states.get("sensor.fake_profile_dnssec_not_validated_queries")
assert state
assert state.state == "25"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dnssec_not_validated_queries")
assert entry
assert entry.unique_id == "xyz12_not_validated_queries"
state = hass.states.get("sensor.fake_profile_dnssec_validated_queries")
assert state
assert state.state == "75"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_dnssec_validated_queries")
assert entry
assert entry.unique_id == "xyz12_validated_queries"
state = hass.states.get("sensor.fake_profile_dnssec_validated_queries_ratio")
assert state
assert state.state == "75.0"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_dnssec_validated_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_validated_queries_ratio"
state = hass.states.get("sensor.fake_profile_encrypted_queries")
assert state
assert state.state == "60"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_encrypted_queries")
assert entry
assert entry.unique_id == "xyz12_encrypted_queries"
state = hass.states.get("sensor.fake_profile_unencrypted_queries")
assert state
assert state.state == "40"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_unencrypted_queries")
assert entry
assert entry.unique_id == "xyz12_unencrypted_queries"
state = hass.states.get("sensor.fake_profile_encrypted_queries_ratio")
assert state
assert state.state == "60.0"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_encrypted_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_encrypted_queries_ratio"
state = hass.states.get("sensor.fake_profile_ipv4_queries")
assert state
assert state.state == "90"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_ipv4_queries")
assert entry
assert entry.unique_id == "xyz12_ipv4_queries"
state = hass.states.get("sensor.fake_profile_ipv6_queries")
assert state
assert state.state == "10"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_ipv6_queries")
assert entry
assert entry.unique_id == "xyz12_ipv6_queries"
state = hass.states.get("sensor.fake_profile_ipv6_queries_ratio")
assert state
assert state.state == "10.0"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_ipv6_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_ipv6_queries_ratio"
state = hass.states.get("sensor.fake_profile_tcp_queries")
assert state
assert state.state == "0"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_tcp_queries")
assert entry
assert entry.unique_id == "xyz12_tcp_queries"
state = hass.states.get("sensor.fake_profile_tcp_queries_ratio")
assert state
assert state.state == "0.0"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_tcp_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_tcp_queries_ratio"
state = hass.states.get("sensor.fake_profile_udp_queries")
assert state
assert state.state == "40"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.TOTAL
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "queries"
entry = registry.async_get("sensor.fake_profile_udp_queries")
assert entry
assert entry.unique_id == "xyz12_udp_queries"
state = hass.states.get("sensor.fake_profile_udp_queries_ratio")
assert state
assert state.state == "34.8"
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
entry = registry.async_get("sensor.fake_profile_udp_queries_ratio")
assert entry
assert entry.unique_id == "xyz12_udp_queries_ratio"
async def test_availability(hass: HomeAssistant) -> None:
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
registry = er.async_get(hass)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_doh_queries",
suggested_object_id="fake_profile_dns_over_https_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_validated_queries",
suggested_object_id="fake_profile_dnssec_validated_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_encrypted_queries",
suggested_object_id="fake_profile_encrypted_queries",
disabled_by=None,
)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"xyz12_ipv4_queries",
suggested_object_id="fake_profile_ipv4_queries",
disabled_by=None,
)
await init_integration(hass)
state = hass.states.get("sensor.fake_profile_dns_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "100"
state = hass.states.get("sensor.fake_profile_dns_over_https_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "20"
state = hass.states.get("sensor.fake_profile_dnssec_validated_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "75"
state = hass.states.get("sensor.fake_profile_encrypted_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "60"
state = hass.states.get("sensor.fake_profile_ipv4_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "90"
future = utcnow() + timedelta(minutes=10)
with patch(
"homeassistant.components.nextdns.NextDns.get_analytics_status",
side_effect=ApiError("API Error"),
), patch(
"homeassistant.components.nextdns.NextDns.get_analytics_dnssec",
side_effect=ApiError("API Error"),
), patch(
"homeassistant.components.nextdns.NextDns.get_analytics_encryption",
side_effect=ApiError("API Error"),
), patch(
"homeassistant.components.nextdns.NextDns.get_analytics_ip_versions",
side_effect=ApiError("API Error"),
), patch(
"homeassistant.components.nextdns.NextDns.get_analytics_protocols",
side_effect=ApiError("API Error"),
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
state = hass.states.get("sensor.fake_profile_dns_queries")
assert state
assert state.state == STATE_UNAVAILABLE
state = hass.states.get("sensor.fake_profile_dns_over_https_queries")
assert state
assert state.state == STATE_UNAVAILABLE
state = hass.states.get("sensor.fake_profile_dnssec_validated_queries")
assert state
assert state.state == STATE_UNAVAILABLE
state = hass.states.get("sensor.fake_profile_encrypted_queries")
assert state
assert state.state == STATE_UNAVAILABLE
state = hass.states.get("sensor.fake_profile_ipv4_queries")
assert state
assert state.state == STATE_UNAVAILABLE
future = utcnow() + timedelta(minutes=20)
with patch(
"homeassistant.components.nextdns.NextDns.get_analytics_status",
return_value=STATUS,
), patch(
"homeassistant.components.nextdns.NextDns.get_analytics_encryption",
return_value=ENCRYPTION,
), patch(
"homeassistant.components.nextdns.NextDns.get_analytics_dnssec",
return_value=DNSSEC,
), patch(
"homeassistant.components.nextdns.NextDns.get_analytics_ip_versions",
return_value=IP_VERSIONS,
), patch(
"homeassistant.components.nextdns.NextDns.get_analytics_protocols",
return_value=PROTOCOLS,
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
state = hass.states.get("sensor.fake_profile_dns_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "100"
state = hass.states.get("sensor.fake_profile_dns_over_https_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "20"
state = hass.states.get("sensor.fake_profile_dnssec_validated_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "75"
state = hass.states.get("sensor.fake_profile_encrypted_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "60"
state = hass.states.get("sensor.fake_profile_ipv4_queries")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "90"