mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 16:57:10 +00:00
Improve AsusWrt test coverage (#70215)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
a27f61cf07
commit
f4d4b52204
@ -83,9 +83,7 @@ omit =
|
|||||||
homeassistant/components/aseko_pool_live/sensor.py
|
homeassistant/components/aseko_pool_live/sensor.py
|
||||||
homeassistant/components/asterisk_cdr/mailbox.py
|
homeassistant/components/asterisk_cdr/mailbox.py
|
||||||
homeassistant/components/asterisk_mbox/*
|
homeassistant/components/asterisk_mbox/*
|
||||||
homeassistant/components/asuswrt/__init__.py
|
|
||||||
homeassistant/components/asuswrt/diagnostics.py
|
homeassistant/components/asuswrt/diagnostics.py
|
||||||
homeassistant/components/asuswrt/router.py
|
|
||||||
homeassistant/components/aten_pe/*
|
homeassistant/components/aten_pe/*
|
||||||
homeassistant/components/atome/*
|
homeassistant/components/atome/*
|
||||||
homeassistant/components/aurora/__init__.py
|
homeassistant/components/aurora/__init__.py
|
||||||
|
@ -277,7 +277,7 @@ class AsusWrtRouter:
|
|||||||
# migrate entity unique ID if wrong formatted
|
# migrate entity unique ID if wrong formatted
|
||||||
if device_mac != entry.unique_id:
|
if device_mac != entry.unique_id:
|
||||||
existing_entity_id = entity_reg.async_get_entity_id(
|
existing_entity_id = entity_reg.async_get_entity_id(
|
||||||
DOMAIN, TRACKER_DOMAIN, device_mac
|
TRACKER_DOMAIN, DOMAIN, device_mac
|
||||||
)
|
)
|
||||||
if existing_entity_id:
|
if existing_entity_id:
|
||||||
# entity with uniqueid properly formatted already
|
# entity with uniqueid properly formatted already
|
||||||
@ -470,11 +470,6 @@ class AsusWrtRouter:
|
|||||||
"""Return sensors coordinators."""
|
"""Return sensors coordinators."""
|
||||||
return self._sensors_coordinator
|
return self._sensors_coordinator
|
||||||
|
|
||||||
@property
|
|
||||||
def api(self) -> AsusWrt:
|
|
||||||
"""Return router API."""
|
|
||||||
return self._api
|
|
||||||
|
|
||||||
|
|
||||||
async def _get_nvram_info(api: AsusWrt, info_type: str) -> dict[str, Any]:
|
async def _get_nvram_info(api: AsusWrt, info_type: str) -> dict[str, Any]:
|
||||||
"""Get AsusWrt router info from nvram."""
|
"""Get AsusWrt router info from nvram."""
|
||||||
|
@ -6,9 +6,10 @@ from aioasuswrt.asuswrt import Device
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components import device_tracker, sensor
|
from homeassistant.components import device_tracker, sensor
|
||||||
from homeassistant.components.asuswrt.const import DOMAIN
|
from homeassistant.components.asuswrt.const import CONF_INTERFACE, DOMAIN
|
||||||
from homeassistant.components.asuswrt.sensor import DEFAULT_PREFIX
|
from homeassistant.components.asuswrt.sensor import DEFAULT_PREFIX
|
||||||
from homeassistant.components.device_tracker.const import CONF_CONSIDER_HOME
|
from homeassistant.components.device_tracker.const import CONF_CONSIDER_HOME
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
@ -18,6 +19,7 @@ from homeassistant.const import (
|
|||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
STATE_HOME,
|
STATE_HOME,
|
||||||
STATE_NOT_HOME,
|
STATE_NOT_HOME,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
@ -31,7 +33,7 @@ IP_ADDRESS = "192.168.1.1"
|
|||||||
CONFIG_DATA = {
|
CONFIG_DATA = {
|
||||||
CONF_HOST: HOST,
|
CONF_HOST: HOST,
|
||||||
CONF_PORT: 22,
|
CONF_PORT: 22,
|
||||||
CONF_PROTOCOL: "ssh",
|
CONF_PROTOCOL: "telnet",
|
||||||
CONF_USERNAME: "user",
|
CONF_USERNAME: "user",
|
||||||
CONF_PASSWORD: "pwd",
|
CONF_PASSWORD: "pwd",
|
||||||
CONF_MODE: "router",
|
CONF_MODE: "router",
|
||||||
@ -41,9 +43,10 @@ MOCK_BYTES_TOTAL = [60000000000, 50000000000]
|
|||||||
MOCK_CURRENT_TRANSFER_RATES = [20000000, 10000000]
|
MOCK_CURRENT_TRANSFER_RATES = [20000000, 10000000]
|
||||||
MOCK_LOAD_AVG = [1.1, 1.2, 1.3]
|
MOCK_LOAD_AVG = [1.1, 1.2, 1.3]
|
||||||
MOCK_TEMPERATURES = {"2.4GHz": 40, "5.0GHz": 0, "CPU": 71.2}
|
MOCK_TEMPERATURES = {"2.4GHz": 40, "5.0GHz": 0, "CPU": 71.2}
|
||||||
MOCK_MAC_1 = "a1:b1:c1:d1:e1:f1"
|
MOCK_MAC_1 = "A1:B1:C1:D1:E1:F1"
|
||||||
MOCK_MAC_2 = "a2:b2:c2:d2:e2:f2"
|
MOCK_MAC_2 = "A2:B2:C2:D2:E2:F2"
|
||||||
MOCK_MAC_3 = "a3:b3:c3:d3:e3:f3"
|
MOCK_MAC_3 = "A3:B3:C3:D3:E3:F3"
|
||||||
|
MOCK_MAC_4 = "A4:B4:C4:D4:E4:F4"
|
||||||
|
|
||||||
SENSOR_NAMES = [
|
SENSOR_NAMES = [
|
||||||
"Devices Connected",
|
"Devices Connected",
|
||||||
@ -79,21 +82,20 @@ def mock_available_temps_list():
|
|||||||
|
|
||||||
@pytest.fixture(name="create_device_registry_devices")
|
@pytest.fixture(name="create_device_registry_devices")
|
||||||
def create_device_registry_devices_fixture(hass):
|
def create_device_registry_devices_fixture(hass):
|
||||||
"""Create device registry devices so the device tracker entities are enabled."""
|
"""Create device registry devices so the device tracker entities are enabled when added."""
|
||||||
dev_reg = dr.async_get(hass)
|
dev_reg = dr.async_get(hass)
|
||||||
config_entry = MockConfigEntry(domain="something_else")
|
config_entry = MockConfigEntry(domain="something_else")
|
||||||
|
|
||||||
for idx, device in enumerate(
|
for idx, device in enumerate(
|
||||||
(
|
(
|
||||||
MOCK_MAC_1,
|
|
||||||
MOCK_MAC_2,
|
|
||||||
MOCK_MAC_3,
|
MOCK_MAC_3,
|
||||||
|
MOCK_MAC_4,
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
dev_reg.async_get_or_create(
|
dev_reg.async_get_or_create(
|
||||||
name=f"Device {idx}",
|
name=f"Device {idx}",
|
||||||
config_entry_id=config_entry.entry_id,
|
config_entry_id=config_entry.entry_id,
|
||||||
connections={(dr.CONNECTION_NETWORK_MAC, device)},
|
connections={(dr.CONNECTION_NETWORK_MAC, dr.format_mac(device))},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -132,14 +134,31 @@ def mock_controller_connect(mock_devices, mock_available_temps):
|
|||||||
yield service_mock
|
yield service_mock
|
||||||
|
|
||||||
|
|
||||||
async def test_sensors(
|
@pytest.fixture(name="connect_sens_fail")
|
||||||
hass,
|
def mock_controller_connect_sens_fail():
|
||||||
connect,
|
"""Mock a successful connection with sensor fail."""
|
||||||
mock_devices,
|
with patch("homeassistant.components.asuswrt.router.AsusWrt") as service_mock:
|
||||||
mock_available_temps,
|
service_mock.return_value.connection.async_connect = AsyncMock()
|
||||||
create_device_registry_devices,
|
service_mock.return_value.is_connected = True
|
||||||
):
|
service_mock.return_value.connection.disconnect = Mock()
|
||||||
"""Test creating an AsusWRT sensor."""
|
service_mock.return_value.async_get_nvram = AsyncMock(side_effect=OSError)
|
||||||
|
service_mock.return_value.async_get_connected_devices = AsyncMock(
|
||||||
|
side_effect=OSError
|
||||||
|
)
|
||||||
|
service_mock.return_value.async_get_bytes_total = AsyncMock(side_effect=OSError)
|
||||||
|
service_mock.return_value.async_get_current_transfer_rates = AsyncMock(
|
||||||
|
side_effect=OSError
|
||||||
|
)
|
||||||
|
service_mock.return_value.async_get_loadavg = AsyncMock(side_effect=OSError)
|
||||||
|
service_mock.return_value.async_get_temperature = AsyncMock(side_effect=OSError)
|
||||||
|
service_mock.return_value.async_find_temperature_commands = AsyncMock(
|
||||||
|
return_value=[True, True, True]
|
||||||
|
)
|
||||||
|
yield service_mock
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_entry(hass):
|
||||||
|
"""Create mock config entry."""
|
||||||
entity_reg = er.async_get(hass)
|
entity_reg = er.async_get(hass)
|
||||||
|
|
||||||
# init config entry
|
# init config entry
|
||||||
@ -165,6 +184,33 @@ async def test_sensors(
|
|||||||
disabled_by=None,
|
disabled_by=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Create the first device tracker to test mac conversion
|
||||||
|
for mac, name in {
|
||||||
|
MOCK_MAC_1: "test",
|
||||||
|
dr.format_mac(MOCK_MAC_2): "testtwo",
|
||||||
|
MOCK_MAC_2: "testremove",
|
||||||
|
}.items():
|
||||||
|
entity_reg.async_get_or_create(
|
||||||
|
device_tracker.DOMAIN,
|
||||||
|
DOMAIN,
|
||||||
|
mac,
|
||||||
|
suggested_object_id=name,
|
||||||
|
config_entry=config_entry,
|
||||||
|
disabled_by=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
return config_entry, sensor_prefix
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensors(
|
||||||
|
hass,
|
||||||
|
connect,
|
||||||
|
mock_devices,
|
||||||
|
mock_available_temps,
|
||||||
|
create_device_registry_devices,
|
||||||
|
):
|
||||||
|
"""Test creating an AsusWRT sensor."""
|
||||||
|
config_entry, sensor_prefix = _setup_entry(hass)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
# initial devices setup
|
# initial devices setup
|
||||||
@ -189,19 +235,22 @@ async def test_sensors(
|
|||||||
assert not hass.states.get(f"{sensor_prefix}_5ghz_temperature")
|
assert not hass.states.get(f"{sensor_prefix}_5ghz_temperature")
|
||||||
assert not hass.states.get(f"{sensor_prefix}_cpu_temperature")
|
assert not hass.states.get(f"{sensor_prefix}_cpu_temperature")
|
||||||
|
|
||||||
# add one device and remove another
|
# remove first track device
|
||||||
mock_devices.pop(MOCK_MAC_1)
|
mock_devices.pop(MOCK_MAC_1)
|
||||||
mock_devices[MOCK_MAC_3] = Device(MOCK_MAC_3, "192.168.1.4", "TestThree")
|
|
||||||
|
|
||||||
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# consider home option set, all devices still home
|
# consider home option set, all devices still home but only 1 device connected
|
||||||
assert hass.states.get(f"{device_tracker.DOMAIN}.test").state == STATE_HOME
|
assert hass.states.get(f"{device_tracker.DOMAIN}.test").state == STATE_HOME
|
||||||
assert hass.states.get(f"{device_tracker.DOMAIN}.testtwo").state == STATE_HOME
|
assert hass.states.get(f"{device_tracker.DOMAIN}.testtwo").state == STATE_HOME
|
||||||
assert hass.states.get(f"{device_tracker.DOMAIN}.testthree").state == STATE_HOME
|
assert hass.states.get(f"{sensor_prefix}_devices_connected").state == "1"
|
||||||
assert hass.states.get(f"{sensor_prefix}_devices_connected").state == "2"
|
|
||||||
|
|
||||||
|
# add 2 new device, one unnamed that should be ignored but counted
|
||||||
|
mock_devices[MOCK_MAC_3] = Device(MOCK_MAC_3, "192.168.1.4", "TestThree")
|
||||||
|
mock_devices[MOCK_MAC_4] = Device(MOCK_MAC_4, "192.168.1.5", None)
|
||||||
|
|
||||||
|
# change consider home settings to have status not home of removed track device
|
||||||
hass.config_entries.async_update_entry(
|
hass.config_entries.async_update_entry(
|
||||||
config_entry, options={CONF_CONSIDER_HOME: 0}
|
config_entry, options={CONF_CONSIDER_HOME: 0}
|
||||||
)
|
)
|
||||||
@ -209,17 +258,86 @@ async def test_sensors(
|
|||||||
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# consider home option not set, device "test" not home
|
# consider home option set to 0, device "test" not home
|
||||||
assert hass.states.get(f"{device_tracker.DOMAIN}.test").state == STATE_NOT_HOME
|
assert hass.states.get(f"{device_tracker.DOMAIN}.test").state == STATE_NOT_HOME
|
||||||
|
assert hass.states.get(f"{device_tracker.DOMAIN}.testtwo").state == STATE_HOME
|
||||||
|
assert hass.states.get(f"{device_tracker.DOMAIN}.testthree").state == STATE_HOME
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_devices_connected").state == "3"
|
||||||
|
|
||||||
# checking temperature sensors without exceptions
|
# checking temperature sensors without exceptions
|
||||||
mock_available_temps.append(True)
|
mock_available_temps.append(True)
|
||||||
await hass.config_entries.async_reload(config_entry.entry_id)
|
await hass.config_entries.async_reload(config_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert hass.states.get(f"{sensor_prefix}_load_avg_15m").state == "1.3"
|
|
||||||
assert hass.states.get(f"{sensor_prefix}_2_4ghz_temperature").state == "40.0"
|
assert hass.states.get(f"{sensor_prefix}_2_4ghz_temperature").state == "40.0"
|
||||||
assert not hass.states.get(f"{sensor_prefix}_5ghz_temperature")
|
assert not hass.states.get(f"{sensor_prefix}_5ghz_temperature")
|
||||||
assert hass.states.get(f"{sensor_prefix}_cpu_temperature").state == "71.2"
|
assert hass.states.get(f"{sensor_prefix}_cpu_temperature").state == "71.2"
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_devices_connected").state == "3"
|
||||||
|
|
||||||
|
# change an option that require integration reload
|
||||||
|
hass.config_entries.async_update_entry(
|
||||||
|
config_entry, options={CONF_CONSIDER_HOME: 60, CONF_INTERFACE: "eth1"}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert config_entry.state is ConfigEntryState.LOADED
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_devices_connected").state == "3"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"side_effect",
|
||||||
|
[OSError, None],
|
||||||
|
)
|
||||||
|
async def test_connect_fail(hass, side_effect):
|
||||||
|
"""Test AsusWRT connect fail."""
|
||||||
|
|
||||||
|
# init config entry
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
data=CONFIG_DATA,
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
with patch("homeassistant.components.asuswrt.router.AsusWrt") as asus_wrt:
|
||||||
|
asus_wrt.return_value.connection.async_connect = AsyncMock(
|
||||||
|
side_effect=side_effect
|
||||||
|
)
|
||||||
|
asus_wrt.return_value.is_connected = False
|
||||||
|
|
||||||
|
# initial setup fail
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensors_polling_fails(
|
||||||
|
hass,
|
||||||
|
connect_sens_fail,
|
||||||
|
):
|
||||||
|
"""Test AsusWRT sensors are unavailable when polling fails."""
|
||||||
|
config_entry, sensor_prefix = _setup_entry(hass)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
# initial devices setup
|
||||||
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_download_speed").state == STATE_UNAVAILABLE
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_download").state == STATE_UNAVAILABLE
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_upload_speed").state == STATE_UNAVAILABLE
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_upload").state == STATE_UNAVAILABLE
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_load_avg_1m").state == STATE_UNAVAILABLE
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_load_avg_5m").state == STATE_UNAVAILABLE
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_load_avg_15m").state == STATE_UNAVAILABLE
|
||||||
|
assert hass.states.get(f"{sensor_prefix}_devices_connected").state == "0"
|
||||||
|
assert (
|
||||||
|
hass.states.get(f"{sensor_prefix}_2_4ghz_temperature").state
|
||||||
|
== STATE_UNAVAILABLE
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
hass.states.get(f"{sensor_prefix}_5ghz_temperature").state == STATE_UNAVAILABLE
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
hass.states.get(f"{sensor_prefix}_cpu_temperature").state == STATE_UNAVAILABLE
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user