"""The tests for the Logger component.""" from collections import defaultdict import logging from unittest.mock import Mock, patch import pytest from homeassistant.components import logger from homeassistant.components.logger import LOGSEVERITY from homeassistant.setup import async_setup_component HASS_NS = "unused.homeassistant" COMPONENTS_NS = f"{HASS_NS}.components" ZONE_NS = f"{COMPONENTS_NS}.zone" GROUP_NS = f"{COMPONENTS_NS}.group" CONFIGED_NS = "otherlibx" UNCONFIG_NS = "unconfigurednamespace" @pytest.fixture(autouse=True) def restore_logging_class(): """Restore logging class.""" klass = logging.getLoggerClass() yield logging.setLoggerClass(klass) async def test_setting_level(hass): """Test we set log levels.""" mocks = defaultdict(Mock) with patch("logging.getLogger", mocks.__getitem__): assert await async_setup_component( hass, "logger", { "logger": { "default": "warning", "logs": { "test": "info", "test.child": "debug", "test.child.child": "warning", }, } }, ) await hass.async_block_till_done() assert len(mocks) == 4 assert len(mocks[""].orig_setLevel.mock_calls) == 1 assert mocks[""].orig_setLevel.mock_calls[0][1][0] == LOGSEVERITY["WARNING"] assert len(mocks["test"].orig_setLevel.mock_calls) == 1 assert mocks["test"].orig_setLevel.mock_calls[0][1][0] == LOGSEVERITY["INFO"] assert len(mocks["test.child"].orig_setLevel.mock_calls) == 1 assert mocks["test.child"].orig_setLevel.mock_calls[0][1][0] == LOGSEVERITY["DEBUG"] assert len(mocks["test.child.child"].orig_setLevel.mock_calls) == 1 assert ( mocks["test.child.child"].orig_setLevel.mock_calls[0][1][0] == LOGSEVERITY["WARNING"] ) # Test set default level with patch("logging.getLogger", mocks.__getitem__): await hass.services.async_call( "logger", "set_default_level", {"level": "fatal"}, blocking=True ) assert len(mocks[""].orig_setLevel.mock_calls) == 2 assert mocks[""].orig_setLevel.mock_calls[1][1][0] == LOGSEVERITY["FATAL"] # Test update other loggers with patch("logging.getLogger", mocks.__getitem__): await hass.services.async_call( "logger", "set_level", {"test.child": "info", "new_logger": "notset"}, blocking=True, ) assert len(mocks) == 5 assert len(mocks["test.child"].orig_setLevel.mock_calls) == 2 assert mocks["test.child"].orig_setLevel.mock_calls[1][1][0] == LOGSEVERITY["INFO"] assert len(mocks["new_logger"].orig_setLevel.mock_calls) == 1 assert ( mocks["new_logger"].orig_setLevel.mock_calls[0][1][0] == LOGSEVERITY["NOTSET"] ) async def test_can_set_level(hass): """Test logger propagation.""" assert await async_setup_component( hass, "logger", { "logger": { "logs": { CONFIGED_NS: "warning", f"{CONFIGED_NS}.info": "info", f"{CONFIGED_NS}.debug": "debug", HASS_NS: "warning", COMPONENTS_NS: "info", ZONE_NS: "debug", GROUP_NS: "info", }, } }, ) assert logging.getLogger(UNCONFIG_NS).level == logging.NOTSET assert logging.getLogger(UNCONFIG_NS).isEnabledFor(logging.CRITICAL) is True assert ( logging.getLogger(f"{UNCONFIG_NS}.any").isEnabledFor(logging.CRITICAL) is True ) assert ( logging.getLogger(f"{UNCONFIG_NS}.any.any").isEnabledFor(logging.CRITICAL) is True ) assert logging.getLogger(CONFIGED_NS).isEnabledFor(logging.DEBUG) is False assert logging.getLogger(CONFIGED_NS).isEnabledFor(logging.WARNING) is True assert logging.getLogger(f"{CONFIGED_NS}.any").isEnabledFor(logging.WARNING) is True assert ( logging.getLogger(f"{CONFIGED_NS}.any.any").isEnabledFor(logging.WARNING) is True ) assert logging.getLogger(f"{CONFIGED_NS}.info").isEnabledFor(logging.DEBUG) is False assert logging.getLogger(f"{CONFIGED_NS}.info").isEnabledFor(logging.INFO) is True assert ( logging.getLogger(f"{CONFIGED_NS}.info.any").isEnabledFor(logging.DEBUG) is False ) assert ( logging.getLogger(f"{CONFIGED_NS}.info.any").isEnabledFor(logging.INFO) is True ) assert logging.getLogger(f"{CONFIGED_NS}.debug").isEnabledFor(logging.DEBUG) is True assert ( logging.getLogger(f"{CONFIGED_NS}.debug.any").isEnabledFor(logging.DEBUG) is True ) assert logging.getLogger(HASS_NS).isEnabledFor(logging.DEBUG) is False assert logging.getLogger(HASS_NS).isEnabledFor(logging.WARNING) is True assert logging.getLogger(COMPONENTS_NS).isEnabledFor(logging.DEBUG) is False assert logging.getLogger(COMPONENTS_NS).isEnabledFor(logging.WARNING) is True assert logging.getLogger(COMPONENTS_NS).isEnabledFor(logging.INFO) is True assert logging.getLogger(GROUP_NS).isEnabledFor(logging.DEBUG) is False assert logging.getLogger(GROUP_NS).isEnabledFor(logging.WARNING) is True assert logging.getLogger(GROUP_NS).isEnabledFor(logging.INFO) is True assert logging.getLogger(f"{GROUP_NS}.any").isEnabledFor(logging.DEBUG) is False assert logging.getLogger(f"{GROUP_NS}.any").isEnabledFor(logging.WARNING) is True assert logging.getLogger(f"{GROUP_NS}.any").isEnabledFor(logging.INFO) is True assert logging.getLogger(ZONE_NS).isEnabledFor(logging.DEBUG) is True assert logging.getLogger(f"{ZONE_NS}.any").isEnabledFor(logging.DEBUG) is True await hass.services.async_call( logger.DOMAIN, "set_level", {f"{UNCONFIG_NS}.any": "debug"}, blocking=True ) logging.getLogger(UNCONFIG_NS).level == logging.NOTSET logging.getLogger(f"{UNCONFIG_NS}.any").level == logging.DEBUG logging.getLogger(UNCONFIG_NS).level == logging.NOTSET await hass.services.async_call( logger.DOMAIN, "set_default_level", {"level": "debug"}, blocking=True ) assert logging.getLogger(UNCONFIG_NS).isEnabledFor(logging.DEBUG) is True assert logging.getLogger(f"{UNCONFIG_NS}.any").isEnabledFor(logging.DEBUG) is True assert ( logging.getLogger(f"{UNCONFIG_NS}.any.any").isEnabledFor(logging.DEBUG) is True ) assert logging.getLogger("").isEnabledFor(logging.DEBUG) is True assert logging.getLogger(COMPONENTS_NS).isEnabledFor(logging.DEBUG) is False assert logging.getLogger(GROUP_NS).isEnabledFor(logging.DEBUG) is False logging.getLogger(CONFIGED_NS).setLevel(logging.INFO) assert logging.getLogger(CONFIGED_NS).level == logging.WARNING logging.getLogger("").setLevel(logging.NOTSET)