Add contextmanager to reset logger after set_level call in tests (#143295)

This commit is contained in:
Marc Mueller 2025-04-20 02:13:01 +02:00 committed by GitHub
parent 961f8afe53
commit 5843e63878
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 304 additions and 318 deletions

View File

@ -46,6 +46,7 @@ from homeassistant.components import device_automation, persistent_notification
from homeassistant.components.device_automation import ( # noqa: F401 from homeassistant.components.device_automation import ( # noqa: F401
_async_get_device_automation_capabilities as async_get_device_automation_capabilities, _async_get_device_automation_capabilities as async_get_device_automation_capabilities,
) )
from homeassistant.components.logger import DOMAIN as LOGGER_DOMAIN, SERVICE_SET_LEVEL
from homeassistant.config import IntegrationConfigInfo, async_process_component_config from homeassistant.config import IntegrationConfigInfo, async_process_component_config
from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult
from homeassistant.const import ( from homeassistant.const import (
@ -1688,6 +1689,28 @@ def async_mock_cloud_connection_status(hass: HomeAssistant, connected: bool) ->
async_dispatcher_send(hass, SIGNAL_CLOUD_CONNECTION_STATE, state) async_dispatcher_send(hass, SIGNAL_CLOUD_CONNECTION_STATE, state)
@asynccontextmanager
async def async_call_logger_set_level(
logger: str,
level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "FATAL", "CRITICAL"],
*,
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
) -> AsyncGenerator[None]:
"""Context manager to reset loggers after logger.set_level call."""
assert LOGGER_DOMAIN in hass.data, "'logger' integration not setup"
with caplog.at_level(logging.NOTSET, logger):
await hass.services.async_call(
LOGGER_DOMAIN,
SERVICE_SET_LEVEL,
{logger: level},
blocking=True,
)
await hass.async_block_till_done()
yield
hass.data[LOGGER_DOMAIN].overrides.clear()
def import_and_test_deprecated_constant_enum( def import_and_test_deprecated_constant_enum(
caplog: pytest.LogCaptureFixture, caplog: pytest.LogCaptureFixture,
module: ModuleType, module: ModuleType,

View File

@ -61,6 +61,7 @@ from . import (
from tests.common import ( from tests.common import (
MockConfigEntry, MockConfigEntry,
MockModule, MockModule,
async_call_logger_set_level,
async_fire_time_changed, async_fire_time_changed,
load_fixture, load_fixture,
mock_integration, mock_integration,
@ -1144,14 +1145,9 @@ async def test_debug_logging(
) -> None: ) -> None:
"""Test debug logging.""" """Test debug logging."""
assert await async_setup_component(hass, "logger", {"logger": {}}) assert await async_setup_component(hass, "logger", {"logger": {}})
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.bluetooth", "DEBUG", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.bluetooth": "DEBUG"},
blocking=True,
)
await hass.async_block_till_done()
address = "44:44:33:11:23:41" address = "44:44:33:11:23:41"
start_time_monotonic = 50.0 start_time_monotonic = 50.0
@ -1171,13 +1167,9 @@ async def test_debug_logging(
assert "wohand_poor_signal_hci0" in caplog.text assert "wohand_poor_signal_hci0" in caplog.text
caplog.clear() caplog.clear()
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.bluetooth", "WARNING", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.bluetooth": "WARNING"},
blocking=True,
)
switchbot_device_good_signal_hci0 = generate_ble_device( switchbot_device_good_signal_hci0 = generate_ble_device(
address, "wohand_good_signal_hci0" address, "wohand_good_signal_hci0"
) )

View File

@ -29,7 +29,11 @@ from . import (
patch_bluetooth_time, patch_bluetooth_time,
) )
from tests.common import MockConfigEntry, async_fire_time_changed from tests.common import (
MockConfigEntry,
async_call_logger_set_level,
async_fire_time_changed,
)
# If the adapter is in a stuck state the following errors are raised: # If the adapter is in a stuck state the following errors are raised:
NEED_RESET_ERRORS = [ NEED_RESET_ERRORS = [
@ -482,12 +486,9 @@ async def test_adapter_fails_to_start_and_takes_a_bit_to_init(
) -> None: ) -> None:
"""Test we can recover the adapter at startup and we wait for Dbus to init.""" """Test we can recover the adapter at startup and we wait for Dbus to init."""
assert await async_setup_component(hass, "logger", {}) assert await async_setup_component(hass, "logger", {})
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.bluetooth", "DEBUG", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.bluetooth": "DEBUG"},
blocking=True,
)
called_start = 0 called_start = 0
called_stop = 0 called_stop = 0
_callback = None _callback = None

View File

@ -49,7 +49,12 @@ from homeassistant.setup import async_setup_component
from .conftest import MockESPHomeDevice from .conftest import MockESPHomeDevice
from tests.common import MockConfigEntry, async_capture_events, async_mock_service from tests.common import (
MockConfigEntry,
async_call_logger_set_level,
async_capture_events,
async_mock_service,
)
async def test_esphome_device_subscribe_logs( async def test_esphome_device_subscribe_logs(
@ -83,12 +88,9 @@ async def test_esphome_device_subscribe_logs(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.esphome", "DEBUG", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.esphome": "DEBUG"},
blocking=True,
)
assert device.current_log_level == LogLevel.LOG_LEVEL_VERY_VERBOSE assert device.current_log_level == LogLevel.LOG_LEVEL_VERY_VERBOSE
caplog.set_level(logging.DEBUG) caplog.set_level(logging.DEBUG)
@ -118,26 +120,17 @@ async def test_esphome_device_subscribe_logs(
await hass.async_block_till_done() await hass.async_block_till_done()
assert "test_debug_log_message" in caplog.text assert "test_debug_log_message" in caplog.text
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.esphome", "WARNING", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.esphome": "WARNING"},
blocking=True,
)
assert device.current_log_level == LogLevel.LOG_LEVEL_WARN assert device.current_log_level == LogLevel.LOG_LEVEL_WARN
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.esphome", "ERROR", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.esphome": "ERROR"},
blocking=True,
)
assert device.current_log_level == LogLevel.LOG_LEVEL_ERROR assert device.current_log_level == LogLevel.LOG_LEVEL_ERROR
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.esphome", "INFO", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.esphome": "INFO"},
blocking=True,
)
assert device.current_log_level == LogLevel.LOG_LEVEL_CONFIG assert device.current_log_level == LogLevel.LOG_LEVEL_CONFIG
@ -961,7 +954,6 @@ async def test_debug_logging(
caplog: pytest.LogCaptureFixture, caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
"""Test enabling and disabling debug logging.""" """Test enabling and disabling debug logging."""
with caplog.at_level(logging.NOTSET, "homeassistant.components.esphome"):
assert await async_setup_component(hass, "logger", {"logger": {}}) assert await async_setup_component(hass, "logger", {"logger": {}})
await mock_generic_device_entry( await mock_generic_device_entry(
mock_client=mock_client, mock_client=mock_client,
@ -969,23 +961,15 @@ async def test_debug_logging(
user_service=[], user_service=[],
states=[], states=[],
) )
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.esphome", "DEBUG", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.esphome": "DEBUG"},
blocking=True,
)
await hass.async_block_till_done()
mock_client.set_debug.assert_has_calls([call(True)]) mock_client.set_debug.assert_has_calls([call(True)])
mock_client.reset_mock() mock_client.reset_mock()
await hass.services.async_call(
"logger", async with async_call_logger_set_level(
"set_level", "homeassistant.components.esphome", "WARNING", hass=hass, caplog=caplog
{"homeassistant.components.esphome": "WARNING"}, ):
blocking=True,
)
await hass.async_block_till_done()
mock_client.set_debug.assert_has_calls([call(False)]) mock_client.set_debug.assert_has_calls([call(False)])

View File

@ -22,7 +22,7 @@ from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from homeassistant.util.ssl import server_context_intermediate, server_context_modern from homeassistant.util.ssl import server_context_intermediate, server_context_modern
from tests.common import async_fire_time_changed from tests.common import async_call_logger_set_level, async_fire_time_changed
from tests.typing import ClientSessionGenerator from tests.typing import ClientSessionGenerator
@ -505,24 +505,18 @@ async def test_logging(
) )
) )
hass.states.async_set("logging.entity", "hello") hass.states.async_set("logging.entity", "hello")
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "aiohttp.access", "INFO", hass=hass, caplog=caplog
"set_level", ):
{"aiohttp.access": "info"},
blocking=True,
)
client = await hass_client() client = await hass_client()
response = await client.get("/api/states/logging.entity") response = await client.get("/api/states/logging.entity")
assert response.status == HTTPStatus.OK assert response.status == HTTPStatus.OK
assert "GET /api/states/logging.entity" in caplog.text assert "GET /api/states/logging.entity" in caplog.text
caplog.clear() caplog.clear()
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "aiohttp.access", "WARNING", hass=hass, caplog=caplog
"set_level", ):
{"aiohttp.access": "warning"},
blocking=True,
)
response = await client.get("/api/states/logging.entity") response = await client.get("/api/states/logging.entity")
assert response.status == HTTPStatus.OK assert response.status == HTTPStatus.OK
assert "GET /api/states/logging.entity" not in caplog.text assert "GET /api/states/logging.entity" not in caplog.text

View File

@ -15,7 +15,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed from tests.common import async_call_logger_set_level, async_fire_time_changed
HASS_NS = "unused.homeassistant" HASS_NS = "unused.homeassistant"
COMPONENTS_NS = f"{HASS_NS}.components" COMPONENTS_NS = f"{HASS_NS}.components"
@ -73,12 +73,9 @@ async def test_log_filtering(
msg_test(filter_logger, True, "format string shouldfilter%s", "not") msg_test(filter_logger, True, "format string shouldfilter%s", "not")
# Filtering should work even if log level is modified # Filtering should work even if log level is modified
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "test.filter", "WARNING", hass=hass, caplog=caplog
"set_level", ):
{"test.filter": "warning"},
blocking=True,
)
assert filter_logger.getEffectiveLevel() == logging.WARNING assert filter_logger.getEffectiveLevel() == logging.WARNING
msg_test( msg_test(
filter_logger, filter_logger,
@ -88,7 +85,9 @@ async def test_log_filtering(
# Filtering should be scoped to a service # Filtering should be scoped to a service
msg_test( msg_test(
filter_logger, True, "this line containing otherfilterer should not be filtered" filter_logger,
True,
"this line containing otherfilterer should not be filtered",
) )
msg_test( msg_test(
logging.getLogger("test.other_filter"), logging.getLogger("test.other_filter"),

View File

@ -19,7 +19,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
from tests.common import async_fire_time_changed from tests.common import async_call_logger_set_level, async_fire_time_changed
from tests.typing import MockHAClientWebSocket, WebSocketGenerator from tests.typing import MockHAClientWebSocket, WebSocketGenerator
@ -533,25 +533,17 @@ async def test_enable_disable_debug_logging(
) -> None: ) -> None:
"""Test enabling and disabling debug logging.""" """Test enabling and disabling debug logging."""
assert await async_setup_component(hass, "logger", {"logger": {}}) assert await async_setup_component(hass, "logger", {"logger": {}})
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.websocket_api", "DEBUG", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.websocket_api": "DEBUG"},
blocking=True,
)
await hass.async_block_till_done()
await websocket_client.send_json({"id": 1, "type": "ping"}) await websocket_client.send_json({"id": 1, "type": "ping"})
msg = await websocket_client.receive_json() msg = await websocket_client.receive_json()
assert msg["id"] == 1 assert msg["id"] == 1
assert msg["type"] == "pong" assert msg["type"] == "pong"
assert 'Sending b\'{"id":1,"type":"pong"}\'' in caplog.text assert 'Sending b\'{"id":1,"type":"pong"}\'' in caplog.text
await hass.services.async_call( async with async_call_logger_set_level(
"logger", "homeassistant.components.websocket_api", "WARNING", hass=hass, caplog=caplog
"set_level", ):
{"homeassistant.components.websocket_api": "WARNING"},
blocking=True,
)
await hass.async_block_till_done()
await websocket_client.send_json({"id": 2, "type": "ping"}) await websocket_client.send_json({"id": 2, "type": "ping"})
msg = await websocket_client.receive_json() msg = await websocket_client.receive_json()
assert msg["id"] == 2 assert msg["id"] == 2

View File

@ -23,7 +23,6 @@ from zwave_js_server.model.node import Node, NodeDataType
from zwave_js_server.model.version import VersionInfo from zwave_js_server.model.version import VersionInfo
from homeassistant.components.hassio import HassioAPIError from homeassistant.components.hassio import HassioAPIError
from homeassistant.components.logger import DOMAIN as LOGGER_DOMAIN, SERVICE_SET_LEVEL
from homeassistant.components.persistent_notification import async_dismiss from homeassistant.components.persistent_notification import async_dismiss
from homeassistant.components.zwave_js import DOMAIN from homeassistant.components.zwave_js import DOMAIN
from homeassistant.components.zwave_js.helpers import get_device_id, get_device_id_ext from homeassistant.components.zwave_js.helpers import get_device_id, get_device_id_ext
@ -42,6 +41,7 @@ from .common import AIR_TEMPERATURE_SENSOR, EATON_RF9640_ENTITY
from tests.common import ( from tests.common import (
MockConfigEntry, MockConfigEntry,
async_call_logger_set_level,
async_fire_time_changed, async_fire_time_changed,
async_get_persistent_notifications, async_get_persistent_notifications,
) )
@ -2018,7 +2018,9 @@ async def test_identify_event(
assert "network with the home ID `3245146787`" in notifications[msg_id]["message"] assert "network with the home ID `3245146787`" in notifications[msg_id]["message"]
async def test_server_logging(hass: HomeAssistant, client: MagicMock) -> None: async def test_server_logging(
hass: HomeAssistant, client: MagicMock, caplog: pytest.LogCaptureFixture
) -> None:
"""Test automatic server logging functionality.""" """Test automatic server logging functionality."""
def _reset_mocks(): def _reset_mocks():
@ -2037,12 +2039,11 @@ async def test_server_logging(hass: HomeAssistant, client: MagicMock) -> None:
# Setup logger and set log level to debug to trigger event listener # Setup logger and set log level to debug to trigger event listener
assert await async_setup_component(hass, "logger", {"logger": {}}) assert await async_setup_component(hass, "logger", {"logger": {}})
assert logging.getLogger("zwave_js_server").getEffectiveLevel() == logging.INFO assert logging.getLogger("zwave_js_server").getEffectiveLevel() == logging.DEBUG
client.async_send_command.reset_mock() client.async_send_command.reset_mock()
await hass.services.async_call( async with async_call_logger_set_level(
LOGGER_DOMAIN, SERVICE_SET_LEVEL, {"zwave_js_server": "debug"}, blocking=True "zwave_js_server", "DEBUG", hass=hass, caplog=caplog
) ):
await hass.async_block_till_done()
assert logging.getLogger("zwave_js_server").getEffectiveLevel() == logging.DEBUG assert logging.getLogger("zwave_js_server").getEffectiveLevel() == logging.DEBUG
# Validate that the server logging was enabled # Validate that the server logging was enabled