Replace util.get_local_ip in favor of components.network.async_get_source_ip() - part 4 (#58669)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Simone Chemelli 2021-11-15 18:18:57 +01:00 committed by GitHub
parent b3ffc1e183
commit 5fc51130ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 83 additions and 125 deletions

View File

@ -124,7 +124,7 @@ class AmbiclimateFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
)
def _cb_url(self):
return f"{get_url(self.hass)}{AUTH_CALLBACK_PATH}"
return f"{get_url(self.hass, prefer_external=True)}{AUTH_CALLBACK_PATH}"
async def _get_authorize_url(self):
oauth = self._generate_oauth()

View File

@ -5,7 +5,6 @@ from aiohttp import web
import voluptuous as vol
from homeassistant.components.network import async_get_source_ip
from homeassistant.components.network.const import PUBLIC_TARGET_IP
from homeassistant.const import (
CONF_ENTITIES,
CONF_TYPE,
@ -106,7 +105,7 @@ ATTR_EMULATED_HUE_NAME = "emulated_hue_name"
async def async_setup(hass, yaml_config):
"""Activate the emulated_hue component."""
local_ip = await async_get_source_ip(hass, PUBLIC_TARGET_IP)
local_ip = await async_get_source_ip(hass)
config = Config(hass, yaml_config.get(DOMAIN, {}), local_ip)
await config.async_setup()

View File

@ -3,7 +3,6 @@ import voluptuous as vol
from homeassistant import config_entries
from homeassistant.components.network import async_get_source_ip
from homeassistant.components.network.const import PUBLIC_TARGET_IP
from homeassistant.const import CONF_NAME
import homeassistant.helpers.config_validation as cv
@ -71,9 +70,7 @@ async def async_setup_entry(hass, config_entry):
name = config[CONF_NAME]
listen_port = config[CONF_LISTEN_PORT]
host_ip = config.get(CONF_HOST_IP) or await async_get_source_ip(
hass, PUBLIC_TARGET_IP
)
host_ip = config.get(CONF_HOST_IP) or await async_get_source_ip(hass)
advertise_ip = config.get(CONF_ADVERTISE_IP)
advertise_port = config.get(CONF_ADVERTISE_PORT)
upnp_bind_multicast = config.get(CONF_UPNP_BIND_MULTICAST)

View File

@ -18,6 +18,7 @@ from homeassistant.components.binary_sensor import (
from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.humidifier import DOMAIN as HUMIDIFIER_DOMAIN
from homeassistant.components.network.const import MDNS_TARGET_IP
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import (
@ -119,8 +120,6 @@ STATUS_WAIT = 3
PORT_CLEANUP_CHECK_INTERVAL_SECS = 1
MDNS_TARGET_IP = "224.0.0.251"
_HOMEKIT_CONFIG_UPDATE_TIME = (
5 # number of seconds to wait for homekit to see the c# change
)

View File

@ -13,6 +13,7 @@ from aiohttp.typedefs import StrOrURL
from aiohttp.web_exceptions import HTTPMovedPermanently, HTTPRedirection
import voluptuous as vol
from homeassistant.components.network import async_get_source_ip
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, SERVER_PORT
from homeassistant.core import Event, HomeAssistant
from homeassistant.helpers import storage
@ -20,7 +21,6 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import bind_hass
from homeassistant.setup import async_start_setup, async_when_setup_or_start
import homeassistant.util as hass_util
from homeassistant.util import ssl as ssl_util
from .auth import setup_auth
@ -190,7 +190,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
hass.http = server
local_ip = await hass.async_add_executor_job(hass_util.get_local_ip)
local_ip = await async_get_source_ip(hass)
host = local_ip
if server_host is not None:

View File

@ -1,7 +1,6 @@
"""Sensor platform for local_ip."""
from homeassistant.components.network import async_get_source_ip
from homeassistant.components.network.const import PUBLIC_TARGET_IP
from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME
@ -33,6 +32,4 @@ class IPSensor(SensorEntity):
async def async_update(self) -> None:
"""Fetch new state data for the sensor."""
self._attr_native_value = await async_get_source_ip(
self.hass, target_ip=PUBLIC_TARGET_IP
)
self._attr_native_value = await async_get_source_ip(self.hass)

View File

@ -2,30 +2,28 @@
from __future__ import annotations
from ipaddress import IPv4Address, IPv6Address, ip_interface
import logging
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import bind_hass
from . import util
from .const import DOMAIN, IPV4_BROADCAST_ADDR
from .const import IPV4_BROADCAST_ADDR, PUBLIC_TARGET_IP
from .models import Adapter
from .network import Network
ZEROCONF_DOMAIN = "zeroconf" # cannot import from zeroconf due to circular dep
_LOGGER = logging.getLogger(__name__)
from .network import Network, async_get_network
@bind_hass
async def async_get_adapters(hass: HomeAssistant) -> list[Adapter]:
"""Get the network adapter configuration."""
network: Network = hass.data[DOMAIN]
network: Network = await async_get_network(hass)
return network.adapters
@bind_hass
async def async_get_source_ip(hass: HomeAssistant, target_ip: str) -> str:
async def async_get_source_ip(
hass: HomeAssistant, target_ip: str = PUBLIC_TARGET_IP
) -> str:
"""Get the source ip for a target ip."""
adapters = await async_get_adapters(hass)
all_ipv4s = []
@ -88,20 +86,10 @@ async def async_get_ipv4_broadcast_addresses(hass: HomeAssistant) -> set[IPv4Add
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up network for Home Assistant."""
hass.data[DOMAIN] = network = Network(hass)
await network.async_setup()
if ZEROCONF_DOMAIN in config:
await network.async_migrate_from_zeroconf(config[ZEROCONF_DOMAIN])
network.async_configure()
_LOGGER.debug("Adapters: %s", network.adapters)
# Avoid circular issue: http->network->websocket_api->http
from .websocket import ( # pylint: disable=import-outside-toplevel
async_register_websocket_commands,
)
async_register_websocket_commands(hass)
return True

View File

@ -11,6 +11,8 @@ DOMAIN: Final = "network"
STORAGE_KEY: Final = "core.network"
STORAGE_VERSION: Final = 1
DATA_NETWORK: Final = "network"
ATTR_ADAPTERS: Final = "adapters"
ATTR_CONFIGURED_ADAPTERS: Final = "configured_adapters"
DEFAULT_CONFIGURED_ADAPTERS: list[str] = []

View File

@ -1,23 +1,35 @@
"""Network helper class for the network integration."""
from __future__ import annotations
import logging
from typing import Any, cast
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.singleton import singleton
from .const import (
ATTR_CONFIGURED_ADAPTERS,
DATA_NETWORK,
DEFAULT_CONFIGURED_ADAPTERS,
STORAGE_KEY,
STORAGE_VERSION,
)
from .models import Adapter
from .util import (
adapters_with_exernal_addresses,
async_load_adapters,
enable_adapters,
enable_auto_detected_adapters,
)
from .util import async_load_adapters, enable_adapters, enable_auto_detected_adapters
_LOGGER = logging.getLogger(__name__)
@singleton(DATA_NETWORK)
@callback
async def async_get_network(hass: HomeAssistant) -> Network:
"""Get network singleton."""
network = Network(hass)
await network.async_setup()
network.async_configure()
_LOGGER.debug("Adapters: %s", network.adapters)
return network
class Network:
@ -41,21 +53,6 @@ class Network:
await self.async_load()
self.adapters = await async_load_adapters()
async def async_migrate_from_zeroconf(self, zc_config: dict[str, Any]) -> None:
"""Migrate configuration from zeroconf."""
if self._data or not zc_config:
return
from homeassistant.components.zeroconf import ( # pylint: disable=import-outside-toplevel
CONF_DEFAULT_INTERFACE,
)
if zc_config.get(CONF_DEFAULT_INTERFACE) is False:
self._data[ATTR_CONFIGURED_ADAPTERS] = adapters_with_exernal_addresses(
self.adapters
)
await self._async_save()
@callback
def async_configure(self) -> None:
"""Configure from storage."""

View File

@ -57,15 +57,6 @@ def enable_auto_detected_adapters(adapters: list[Adapter]) -> None:
)
def adapters_with_exernal_addresses(adapters: list[Adapter]) -> list[str]:
"""Enable all interfaces with an external address."""
return [
adapter["name"]
for adapter in adapters
if _adapter_has_external_address(adapter)
]
def _adapter_has_external_address(adapter: Adapter) -> bool:
"""Adapter has a non-loopback and non-link-local address."""
return any(

View File

@ -7,13 +7,8 @@ from homeassistant.components import websocket_api
from homeassistant.components.websocket_api.connection import ActiveConnection
from homeassistant.core import HomeAssistant, callback
from .const import (
ATTR_ADAPTERS,
ATTR_CONFIGURED_ADAPTERS,
DOMAIN,
NETWORK_CONFIG_SCHEMA,
)
from .network import Network
from .const import ATTR_ADAPTERS, ATTR_CONFIGURED_ADAPTERS, NETWORK_CONFIG_SCHEMA
from .network import async_get_network
@callback
@ -32,7 +27,7 @@ async def websocket_network_adapters(
msg: dict,
) -> None:
"""Return network preferences."""
network: Network = hass.data[DOMAIN]
network = await async_get_network(hass)
connection.send_result(
msg["id"],
{
@ -56,7 +51,7 @@ async def websocket_network_adapters_configure(
msg: dict,
) -> None:
"""Update network config."""
network: Network = hass.data[DOMAIN]
network = await async_get_network(hass)
await network.async_reconfig(msg["config"])

View File

@ -17,6 +17,7 @@ from zeroconf.asyncio import AsyncServiceInfo
from homeassistant import config_entries
from homeassistant.components import network
from homeassistant.components.network import async_get_source_ip
from homeassistant.components.network.const import MDNS_TARGET_IP
from homeassistant.components.network.models import Adapter
from homeassistant.const import (
EVENT_HOMEASSISTANT_START,
@ -52,8 +53,6 @@ DEFAULT_IPV6 = True
HOMEKIT_PAIRED_STATUS_FLAG = "sf"
HOMEKIT_MODEL = "md"
MDNS_TARGET_IP = "224.0.0.251"
# Property key=value has a max length of 255
# so we use 230 to leave space for key=
MAX_PROPERTY_VALUE_LEN = 230

View File

@ -5,10 +5,9 @@ import asyncio
from collections.abc import Callable, Coroutine, Iterable, KeysView
from datetime import datetime, timedelta
import enum
from functools import lru_cache, wraps
from functools import wraps
import random
import re
import socket
import string
import threading
from types import MappingProxyType
@ -129,26 +128,6 @@ def ensure_unique_string(
return test_string
# Taken from: http://stackoverflow.com/a/11735897
@lru_cache(maxsize=None)
def get_local_ip() -> str:
"""Try to determine the local IP address of the machine."""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Use Google Public DNS server to determine own IP
sock.connect(("8.8.8.8", 80))
return sock.getsockname()[0] # type: ignore
except OSError:
try:
return socket.gethostbyname(socket.gethostname())
except socket.gaierror:
return "127.0.0.1"
finally:
sock.close()
# Taken from http://stackoverflow.com/a/23728630
def get_random_string(length: int = 10) -> str:
"""Return a random string with letters and digits."""

View File

@ -12,6 +12,7 @@ bcrypt==3.1.7
certifi>=2021.5.30
ciso8601==2.2.0
httpx==0.19.0
ifaddr==0.1.7
jinja2==3.0.3
PyJWT==2.1.0
cryptography==35.0.0

View File

@ -134,8 +134,8 @@ IGNORE_VIOLATIONS = {
# Demo
("demo", "manual"),
("demo", "openalpr_local"),
# Migration of settings from zeroconf to network
("network", "zeroconf"),
# This would be a circular dep
("http", "network"),
# This should become a helper method that integrations can submit data to
("websocket_api", "lovelace"),
("websocket_api", "shopping_list"),

View File

@ -43,6 +43,7 @@ REQUIRES = [
"certifi>=2021.5.30",
"ciso8601==2.2.0",
"httpx==0.19.0",
"ifaddr==0.1.7",
"jinja2==3.0.3",
"PyJWT==2.1.0",
# PyJWT has loose dependency. We want the latest one.

View File

@ -179,7 +179,10 @@ async def setup_mock_motioneye_config_entry(
await async_process_ha_core_config(
hass,
{"external_url": "https://example.com"},
{
"internal_url": "https://internal.url",
"external_url": "https://external.url",
},
)
config_entry = config_entry or create_mock_motioneye_config_entry(hass)

View File

@ -77,7 +77,7 @@ async def test_setup_camera_without_webhook(hass: HomeAssistant) -> None:
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_ENABLED] = True
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_URL] = (
"https://example.com"
"https://internal.url"
+ URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID])
+ f"?{WEB_HOOK_MOTION_DETECTED_QUERY_STRING}&device_id={device.id}"
)
@ -85,7 +85,7 @@ async def test_setup_camera_without_webhook(hass: HomeAssistant) -> None:
expected_camera[KEY_WEB_HOOK_STORAGE_ENABLED] = True
expected_camera[KEY_WEB_HOOK_STORAGE_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON
expected_camera[KEY_WEB_HOOK_STORAGE_URL] = (
"https://example.com"
"https://internal.url"
+ URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID])
+ f"?{WEB_HOOK_FILE_STORED_QUERY_STRING}&device_id={device.id}"
)
@ -132,7 +132,7 @@ async def test_setup_camera_with_wrong_webhook(
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_ENABLED] = True
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_URL] = (
"https://example.com"
"https://internal.url"
+ URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID])
+ f"?{WEB_HOOK_MOTION_DETECTED_QUERY_STRING}&device_id={device.id}"
)
@ -140,7 +140,7 @@ async def test_setup_camera_with_wrong_webhook(
expected_camera[KEY_WEB_HOOK_STORAGE_ENABLED] = True
expected_camera[KEY_WEB_HOOK_STORAGE_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON
expected_camera[KEY_WEB_HOOK_STORAGE_URL] = (
"https://example.com"
"https://internal.url"
+ URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID])
+ f"?{WEB_HOOK_FILE_STORED_QUERY_STRING}&device_id={device.id}"
)
@ -185,7 +185,7 @@ async def test_setup_camera_with_old_webhook(
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_ENABLED] = True
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON
expected_camera[KEY_WEB_HOOK_NOTIFICATIONS_URL] = (
"https://example.com"
"https://internal.url"
+ URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID])
+ f"?{WEB_HOOK_MOTION_DETECTED_QUERY_STRING}&device_id={device.id}"
)
@ -193,7 +193,7 @@ async def test_setup_camera_with_old_webhook(
expected_camera[KEY_WEB_HOOK_STORAGE_ENABLED] = True
expected_camera[KEY_WEB_HOOK_STORAGE_HTTP_METHOD] = KEY_HTTP_METHOD_POST_JSON
expected_camera[KEY_WEB_HOOK_STORAGE_URL] = (
"https://example.com"
"https://internal.url"
+ URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID])
+ f"?{WEB_HOOK_FILE_STORED_QUERY_STRING}&device_id={device.id}"
)
@ -223,7 +223,7 @@ async def test_setup_camera_with_correct_webhook(
KEY_WEB_HOOK_NOTIFICATIONS_HTTP_METHOD
] = KEY_HTTP_METHOD_POST_JSON
cameras[KEY_CAMERAS][0][KEY_WEB_HOOK_NOTIFICATIONS_URL] = (
"https://example.com"
"https://internal.url"
+ URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID])
+ f"?{WEB_HOOK_MOTION_DETECTED_QUERY_STRING}&device_id={device.id}"
)
@ -232,7 +232,7 @@ async def test_setup_camera_with_correct_webhook(
KEY_WEB_HOOK_STORAGE_HTTP_METHOD
] = KEY_HTTP_METHOD_POST_JSON
cameras[KEY_CAMERAS][0][KEY_WEB_HOOK_STORAGE_URL] = (
"https://example.com"
"https://internal.url"
+ URL_WEBHOOK_PATH.format(webhook_id=config_entry.data[CONF_WEBHOOK_ID])
+ f"?{WEB_HOOK_FILE_STORED_QUERY_STRING}&device_id={device.id}"
)

View File

@ -0,0 +1,9 @@
"""Tests for the Network Configuration integration."""
import pytest
@pytest.fixture(autouse=True)
def mock_get_source_ip():
"""Override mock of network util's async_get_source_ip."""
return

View File

@ -8,6 +8,7 @@ from homeassistant.components import network
from homeassistant.components.network.const import (
ATTR_ADAPTERS,
ATTR_CONFIGURED_ADAPTERS,
DOMAIN,
MDNS_TARGET_IP,
STORAGE_KEY,
STORAGE_VERSION,
@ -59,10 +60,10 @@ async def test_async_detect_interfaces_setting_non_loopback_route(hass, hass_sto
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=_generate_mock_adapters(),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
network_obj = hass.data[network.DOMAIN]
network_obj = hass.data[DOMAIN]
assert network_obj.configured_adapters == []
assert network_obj.adapters == [
@ -121,10 +122,10 @@ async def test_async_detect_interfaces_setting_loopback_route(hass, hass_storage
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=_generate_mock_adapters(),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
network_obj = hass.data[network.DOMAIN]
network_obj = hass.data[DOMAIN]
assert network_obj.configured_adapters == []
assert network_obj.adapters == [
{
@ -182,10 +183,10 @@ async def test_async_detect_interfaces_setting_empty_route(hass, hass_storage):
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=_generate_mock_adapters(),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
network_obj = hass.data[network.DOMAIN]
network_obj = hass.data[DOMAIN]
assert network_obj.configured_adapters == []
assert network_obj.adapters == [
{
@ -243,10 +244,10 @@ async def test_async_detect_interfaces_setting_exception(hass, hass_storage):
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=_generate_mock_adapters(),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
network_obj = hass.data[network.DOMAIN]
network_obj = hass.data[DOMAIN]
assert network_obj.configured_adapters == []
assert network_obj.adapters == [
{
@ -309,10 +310,10 @@ async def test_interfaces_configured_from_storage(hass, hass_storage):
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=_generate_mock_adapters(),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
network_obj = hass.data[network.DOMAIN]
network_obj = hass.data[DOMAIN]
assert network_obj.configured_adapters == ["eth0", "eth1", "vtun0"]
assert network_obj.adapters == [
@ -378,10 +379,10 @@ async def test_interfaces_configured_from_storage_websocket_update(
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=_generate_mock_adapters(),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
network_obj = hass.data[network.DOMAIN]
network_obj = hass.data[DOMAIN]
assert network_obj.configured_adapters == ["eth0", "eth1", "vtun0"]
ws_client = await hass_ws_client(hass)
await ws_client.send_json({"id": 1, "type": "network"})
@ -507,7 +508,7 @@ async def test_async_get_source_ip_matching_interface(hass, hass_storage):
"homeassistant.components.network.util.socket.socket",
return_value=_mock_socket(["192.168.1.5"]),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
assert await network.async_get_source_ip(hass, MDNS_TARGET_IP) == "192.168.1.5"
@ -528,7 +529,7 @@ async def test_async_get_source_ip_interface_not_match(hass, hass_storage):
"homeassistant.components.network.util.socket.socket",
return_value=_mock_socket(["192.168.1.5"]),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
assert await network.async_get_source_ip(hass, MDNS_TARGET_IP) == "169.254.3.2"
@ -549,7 +550,7 @@ async def test_async_get_source_ip_cannot_determine_target(hass, hass_storage):
"homeassistant.components.network.util.socket.socket",
return_value=_mock_socket([None]),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
assert await network.async_get_source_ip(hass, MDNS_TARGET_IP) == "192.168.1.5"
@ -570,7 +571,7 @@ async def test_async_get_ipv4_broadcast_addresses_default(hass, hass_storage):
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=_generate_mock_adapters(),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
assert await network.async_get_ipv4_broadcast_addresses(hass) == {
@ -593,7 +594,7 @@ async def test_async_get_ipv4_broadcast_addresses_multiple(hass, hass_storage):
"homeassistant.components.network.util.ifaddr.get_adapters",
return_value=_generate_mock_adapters(),
):
assert await async_setup_component(hass, network.DOMAIN, {network.DOMAIN: {}})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
assert await network.async_get_ipv4_broadcast_addresses(hass) == {

View File

@ -598,7 +598,7 @@ async def mqtt_mock(hass, mqtt_client_mock, mqtt_config):
return component
@pytest.fixture
@pytest.fixture(autouse=True)
def mock_get_source_ip():
"""Mock network util's async_get_source_ip."""
with patch(