Migrate to using aiohttp-asyncmdnsresolver for aiohttp resolver (#134830)
parent
d13c14eedb
commit
89c73f56b1
|
@ -144,17 +144,27 @@ class ZeroconfServiceInfo(BaseServiceInfo):
|
|||
|
||||
@bind_hass
|
||||
async def async_get_instance(hass: HomeAssistant) -> HaZeroconf:
|
||||
"""Zeroconf instance to be shared with other integrations that use it."""
|
||||
return cast(HaZeroconf, (await _async_get_instance(hass)).zeroconf)
|
||||
"""Get or create the shared HaZeroconf instance."""
|
||||
return cast(HaZeroconf, (_async_get_instance(hass)).zeroconf)
|
||||
|
||||
|
||||
@bind_hass
|
||||
async def async_get_async_instance(hass: HomeAssistant) -> HaAsyncZeroconf:
|
||||
"""Zeroconf instance to be shared with other integrations that use it."""
|
||||
return await _async_get_instance(hass)
|
||||
"""Get or create the shared HaAsyncZeroconf instance."""
|
||||
return _async_get_instance(hass)
|
||||
|
||||
|
||||
async def _async_get_instance(hass: HomeAssistant, **zcargs: Any) -> HaAsyncZeroconf:
|
||||
@callback
|
||||
def async_get_async_zeroconf(hass: HomeAssistant) -> HaAsyncZeroconf:
|
||||
"""Get or create the shared HaAsyncZeroconf instance.
|
||||
|
||||
This method must be run in the event loop, and is an alternative
|
||||
to the async_get_async_instance method when a coroutine cannot be used.
|
||||
"""
|
||||
return _async_get_instance(hass)
|
||||
|
||||
|
||||
def _async_get_instance(hass: HomeAssistant, **zcargs: Any) -> HaAsyncZeroconf:
|
||||
if DOMAIN in hass.data:
|
||||
return cast(HaAsyncZeroconf, hass.data[DOMAIN])
|
||||
|
||||
|
@ -221,7 +231,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
)
|
||||
]
|
||||
|
||||
aio_zc = await _async_get_instance(hass, **zc_args)
|
||||
aio_zc = _async_get_instance(hass, **zc_args)
|
||||
zeroconf = cast(HaZeroconf, aio_zc.zeroconf)
|
||||
zeroconf_types = await async_get_zeroconf(hass)
|
||||
homekit_models = await async_get_homekit(hass)
|
||||
|
|
|
@ -14,10 +14,11 @@ from typing import TYPE_CHECKING, Any, Self
|
|||
import aiohttp
|
||||
from aiohttp import web
|
||||
from aiohttp.hdrs import CONTENT_TYPE, USER_AGENT
|
||||
from aiohttp.resolver import AsyncResolver
|
||||
from aiohttp.web_exceptions import HTTPBadGateway, HTTPGatewayTimeout
|
||||
from aiohttp_asyncmdnsresolver.api import AsyncMDNSResolver
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.const import APPLICATION_NAME, EVENT_HOMEASSISTANT_CLOSE, __version__
|
||||
from homeassistant.core import Event, HomeAssistant, callback
|
||||
from homeassistant.loader import bind_hass
|
||||
|
@ -362,7 +363,7 @@ def _async_get_connector(
|
|||
ssl=ssl_context,
|
||||
limit=MAXIMUM_CONNECTIONS,
|
||||
limit_per_host=MAXIMUM_CONNECTIONS_PER_HOST,
|
||||
resolver=AsyncResolver(),
|
||||
resolver=_async_make_resolver(hass),
|
||||
)
|
||||
connectors[connector_key] = connector
|
||||
|
||||
|
@ -373,3 +374,8 @@ def _async_get_connector(
|
|||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, _async_close_connector)
|
||||
|
||||
return connector
|
||||
|
||||
|
||||
@callback
|
||||
def _async_make_resolver(hass: HomeAssistant) -> AsyncMDNSResolver:
|
||||
return AsyncMDNSResolver(async_zeroconf=zeroconf.async_get_async_zeroconf(hass))
|
||||
|
|
|
@ -4,6 +4,7 @@ aiodhcpwatcher==1.0.2
|
|||
aiodiscover==2.1.0
|
||||
aiodns==3.2.0
|
||||
aiohasupervisor==0.2.2b5
|
||||
aiohttp-asyncmdnsresolver==0.0.1
|
||||
aiohttp-fast-zlib==0.2.0
|
||||
aiohttp==3.11.11
|
||||
aiohttp_cors==0.7.0
|
||||
|
|
|
@ -32,6 +32,7 @@ dependencies = [
|
|||
"aiohttp==3.11.11",
|
||||
"aiohttp_cors==0.7.0",
|
||||
"aiohttp-fast-zlib==0.2.0",
|
||||
"aiohttp-asyncmdnsresolver==0.0.1",
|
||||
"aiozoneinfo==0.2.1",
|
||||
"astral==2.2",
|
||||
"async-interrupt==1.2.0",
|
||||
|
@ -82,6 +83,7 @@ dependencies = [
|
|||
"voluptuous-openapi==0.0.5",
|
||||
"yarl==1.18.3",
|
||||
"webrtc-models==0.3.0",
|
||||
"zeroconf==0.136.2"
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
|
|
@ -8,6 +8,7 @@ aiohasupervisor==0.2.2b5
|
|||
aiohttp==3.11.11
|
||||
aiohttp_cors==0.7.0
|
||||
aiohttp-fast-zlib==0.2.0
|
||||
aiohttp-asyncmdnsresolver==0.0.1
|
||||
aiozoneinfo==0.2.1
|
||||
astral==2.2
|
||||
async-interrupt==1.2.0
|
||||
|
@ -50,3 +51,4 @@ voluptuous-serialize==2.6.0
|
|||
voluptuous-openapi==0.0.5
|
||||
yarl==1.18.3
|
||||
webrtc-models==0.3.0
|
||||
zeroconf==0.136.2
|
||||
|
|
|
@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any, cast
|
|||
from unittest.mock import AsyncMock, MagicMock, Mock, _patch, patch
|
||||
|
||||
from aiohttp import client
|
||||
from aiohttp.resolver import AsyncResolver
|
||||
from aiohttp.test_utils import (
|
||||
BaseTestServer,
|
||||
TestClient,
|
||||
|
@ -1220,6 +1221,30 @@ def disable_translations_once(
|
|||
translations_once.start()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="session")
|
||||
def mock_zeroconf_resolver() -> Generator[_patch]:
|
||||
"""Mock out the zeroconf resolver."""
|
||||
patcher = patch(
|
||||
"homeassistant.helpers.aiohttp_client._async_make_resolver",
|
||||
return_value=AsyncResolver(),
|
||||
)
|
||||
patcher.start()
|
||||
try:
|
||||
yield patcher
|
||||
finally:
|
||||
patcher.stop()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def disable_mock_zeroconf_resolver(
|
||||
mock_zeroconf_resolver: _patch,
|
||||
) -> Generator[None]:
|
||||
"""Disable the zeroconf resolver."""
|
||||
mock_zeroconf_resolver.stop()
|
||||
yield
|
||||
mock_zeroconf_resolver.start()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_zeroconf() -> Generator[MagicMock]:
|
||||
"""Mock zeroconf."""
|
||||
|
|
|
@ -390,3 +390,16 @@ async def test_client_session_immutable_headers(hass: HomeAssistant) -> None:
|
|||
|
||||
with pytest.raises(AttributeError):
|
||||
session.headers.update({"user-agent": "bla"})
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("disable_mock_zeroconf_resolver")
|
||||
@pytest.mark.usefixtures("mock_async_zeroconf")
|
||||
async def test_async_mdnsresolver(
|
||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
||||
) -> None:
|
||||
"""Test async_mdnsresolver."""
|
||||
resp = aioclient_mock.post("http://localhost/xyz", json={"x": 1})
|
||||
session = client.async_create_clientsession(hass)
|
||||
resp = await session.post("http://localhost/xyz", json={"x": 1})
|
||||
assert resp.status == 200
|
||||
assert await resp.json() == {"x": 1}
|
||||
|
|
|
@ -1392,9 +1392,13 @@ async def test_bootstrap_does_not_preload_stage_1_integrations() -> None:
|
|||
assert process.returncode == 0
|
||||
decoded_stdout = stdout.decode()
|
||||
|
||||
disallowed_integrations = bootstrap.STAGE_1_INTEGRATIONS.copy()
|
||||
# zeroconf is a top level dep now
|
||||
disallowed_integrations.remove("zeroconf")
|
||||
|
||||
# Ensure no stage1 integrations have been imported
|
||||
# as a side effect of importing the pre-imports
|
||||
for integration in bootstrap.STAGE_1_INTEGRATIONS:
|
||||
for integration in disallowed_integrations:
|
||||
assert f"homeassistant.components.{integration}" not in decoded_stdout
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue