mirror of
https://github.com/elisspace/core.git
synced 2026-08-29 15:43:55 +00:00
Add profiler service to investigate ssl object leaks
related issue https://github.com/aio-libs/aiohttp/issues/7252 related PR https://github.com/home-assistant/core/pull/93013
This commit is contained in:
@@ -4,7 +4,6 @@ from asyncio.sslproto import SSLProtocol, _SSLProtocolTransport
|
||||
from contextlib import suppress
|
||||
from datetime import timedelta
|
||||
from functools import _lru_cache_wrapper
|
||||
import json
|
||||
import logging
|
||||
import reprlib
|
||||
import ssl
|
||||
@@ -22,10 +21,8 @@ from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_SCAN_INTERVAL, CONF_TYPE
|
||||
from homeassistant.core import HomeAssistant, ServiceCall, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import template
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.event import async_track_time_interval
|
||||
from homeassistant.helpers.json import ExtendedJSONEncoder
|
||||
from homeassistant.helpers.service import async_register_admin_service
|
||||
|
||||
from .const import DOMAIN
|
||||
@@ -88,9 +85,6 @@ async def async_setup_entry( # noqa: C901
|
||||
domain_data = hass.data[DOMAIN] = {}
|
||||
|
||||
async def _async_run_profile(call: ServiceCall) -> None:
|
||||
_LOGGER.warning(
|
||||
"Modules: %s", json.dumps(sys.modules, indent=2, cls=ExtendedJSONEncoder)
|
||||
)
|
||||
async with lock:
|
||||
await _async_generate_profile(hass, call)
|
||||
|
||||
@@ -218,15 +212,6 @@ async def async_setup_entry( # noqa: C901
|
||||
maybe_lru.get_stats(),
|
||||
)
|
||||
|
||||
_LOGGER.critical(
|
||||
"Cache stats for LRU template_states: %s",
|
||||
template.CACHED_TEMPLATE_LRU.get_stats(), # type: ignore[attr-defined]
|
||||
)
|
||||
_LOGGER.critical(
|
||||
"Cache stats for LRU template_states_no_collect: %s",
|
||||
template.CACHED_TEMPLATE_NO_COLLECT_LRU.get_stats(), # type: ignore[attr-defined]
|
||||
)
|
||||
|
||||
for lru in objgraph.by_type(_SQLALCHEMY_LRU_OBJECT):
|
||||
if (data := getattr(lru, "_data", None)) and isinstance(data, dict):
|
||||
for key, value in dict(data).items():
|
||||
|
||||
@@ -15,6 +15,7 @@ from homeassistant.components.profiler import (
|
||||
CONF_SECONDS,
|
||||
SERVICE_DUMP_LOG_OBJECTS,
|
||||
SERVICE_LOG_EVENT_LOOP_SCHEDULED,
|
||||
SERVICE_LOG_SSL,
|
||||
SERVICE_LOG_THREAD_FRAMES,
|
||||
SERVICE_LRU_STATS,
|
||||
SERVICE_MEMORY,
|
||||
@@ -387,3 +388,56 @@ async def test_log_object_sources(
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_STOP_LOG_OBJECT_SOURCES, {}, blocking=True
|
||||
)
|
||||
|
||||
|
||||
async def test_log_ssl(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) -> None:
|
||||
"""Test logging ssl objects."""
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
class SSLProtocol:
|
||||
def __init__(self):
|
||||
"""Mock an SSLProtocol."""
|
||||
self._transport = None
|
||||
|
||||
class SSLObject:
|
||||
def __init__(self):
|
||||
"""Mock an SSLObject."""
|
||||
self._transport = None
|
||||
|
||||
def getpeercert(self, binary_form=False):
|
||||
"""Mock getpeercert."""
|
||||
return {"subject": (("commonName", "test"),)}
|
||||
|
||||
def server_hostname(self):
|
||||
"""Mock server_hostname."""
|
||||
return "test"
|
||||
|
||||
class _SSLProtocolTransport:
|
||||
def __init__(self):
|
||||
"""Mock an _SSLProtocolTransport."""
|
||||
|
||||
ssl_protocol = SSLProtocol()
|
||||
ssl_object = SSLObject()
|
||||
ssl_protocol_transport = _SSLProtocolTransport()
|
||||
assert hass.services.has_service(DOMAIN, SERVICE_LOG_SSL)
|
||||
|
||||
def _mock_by_type(type_):
|
||||
if type_ == "SSLProtocol":
|
||||
return [ssl_protocol]
|
||||
if type_ == "SSLObject":
|
||||
return [ssl_object]
|
||||
if type_ == "_SSLProtocolTransport":
|
||||
return [ssl_protocol_transport]
|
||||
raise ValueError("Unknown type")
|
||||
|
||||
with patch("objgraph.by_type", side_effect=_mock_by_type):
|
||||
await hass.services.async_call(DOMAIN, SERVICE_LOG_SSL, blocking=True)
|
||||
|
||||
assert "SSLProtocol" in caplog.text
|
||||
assert "SSLObject" in caplog.text
|
||||
assert "_SSLProtocolTransport" in caplog.text
|
||||
|
||||
Reference in New Issue
Block a user