diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 5db58aaa8f0..9512c0a3663 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -619,13 +619,18 @@ async def async_enable_logging( logger = logging.getLogger() logger.setLevel(logging.INFO if verbose else logging.WARNING) - # Log errors to a file if we have write access to file or config dir if log_file is None: + default_log_path = hass.config.path(ERROR_LOG_FILENAME) if "SUPERVISOR" in os.environ: _LOGGER.info("Running in Supervisor, not logging to file") + # Delete the default log file if it exists, since previous versions created + # it even on Supervisor + if os.path.isfile(default_log_path): + with contextlib.suppress(OSError): + os.remove(default_log_path) err_log_path = None else: - err_log_path = hass.config.path(ERROR_LOG_FILENAME) + err_log_path = default_log_path else: err_log_path = os.path.abspath(log_file) diff --git a/tests/test_bootstrap.py b/tests/test_bootstrap.py index 4c22129b023..9a1dac551fd 100644 --- a/tests/test_bootstrap.py +++ b/tests/test_bootstrap.py @@ -38,6 +38,17 @@ from .common import ( VERSION_PATH = os.path.join(get_test_config_dir(), config_util.VERSION_FILE) +CONFIG_LOG_FILE_PATTERN = get_test_config_dir("home-assistant.log*") +ARG_LOG_FILE_PATTERN = "test.log*" + + +def cleanup_log_files() -> None: + """Remove all log files.""" + for f in glob.glob(CONFIG_LOG_FILE_PATTERN): + os.remove(f) + for f in glob.glob(ARG_LOG_FILE_PATTERN): + os.remove(f) + @pytest.fixture(autouse=True) def disable_installed_check() -> Generator[None]: @@ -85,20 +96,11 @@ async def test_async_enable_logging( hass: HomeAssistant, caplog: pytest.LogCaptureFixture ) -> None: """Test to ensure logging is migrated to the queue handlers.""" - config_log_file_pattern = get_test_config_dir("home-assistant.log*") - arg_log_file_pattern = "test.log*" - - def cleanup_log_files() -> None: - """Remove all log files.""" - for f in glob.glob(config_log_file_pattern): - os.remove(f) - for f in glob.glob(arg_log_file_pattern): - os.remove(f) # Ensure we start with a clean slate cleanup_log_files() - assert len(glob.glob(config_log_file_pattern)) == 0 - assert len(glob.glob(arg_log_file_pattern)) == 0 + assert len(glob.glob(CONFIG_LOG_FILE_PATTERN)) == 0 + assert len(glob.glob(ARG_LOG_FILE_PATTERN)) == 0 with ( patch("logging.getLogger"), @@ -112,7 +114,7 @@ async def test_async_enable_logging( ): await bootstrap.async_enable_logging(hass) mock_async_activate_log_queue_handler.assert_called_once() - assert len(glob.glob(config_log_file_pattern)) > 0 + assert len(glob.glob(CONFIG_LOG_FILE_PATTERN)) > 0 mock_async_activate_log_queue_handler.reset_mock() await bootstrap.async_enable_logging( @@ -121,33 +123,57 @@ async def test_async_enable_logging( log_file="test.log", ) mock_async_activate_log_queue_handler.assert_called_once() - assert len(glob.glob(arg_log_file_pattern)) > 0 + assert len(glob.glob(ARG_LOG_FILE_PATTERN)) > 0 assert "Error rolling over log file" in caplog.text cleanup_log_files() + +async def test_async_enable_logging_supervisor( + hass: HomeAssistant, caplog: pytest.LogCaptureFixture +) -> None: + """Test to ensure the default log file is not created on Supervisor installations.""" + + # Ensure we start with a clean slate + cleanup_log_files() + assert len(glob.glob(CONFIG_LOG_FILE_PATTERN)) == 0 + assert len(glob.glob(ARG_LOG_FILE_PATTERN)) == 0 + with ( patch.dict(os.environ, {"SUPERVISOR": "1"}), - patch("logging.getLogger"), patch( "homeassistant.bootstrap.async_activate_log_queue_handler" ) as mock_async_activate_log_queue_handler, + patch("logging.getLogger"), ): await bootstrap.async_enable_logging(hass) + assert len(glob.glob(CONFIG_LOG_FILE_PATTERN)) == 0 mock_async_activate_log_queue_handler.assert_called_once() - # On Supervisor, the default log file should not be created - assert len(glob.glob(config_log_file_pattern)) == 0 - mock_async_activate_log_queue_handler.reset_mock() + + # Check that if the log file exists, it is removed + def write_log_file(): + with open( + get_test_config_dir("home-assistant.log"), "w", encoding="utf8" + ) as f: + f.write("test") + + await hass.async_add_executor_job(write_log_file) + assert len(glob.glob(CONFIG_LOG_FILE_PATTERN)) == 1 + await bootstrap.async_enable_logging(hass) + assert len(glob.glob(CONFIG_LOG_FILE_PATTERN)) == 0 + mock_async_activate_log_queue_handler.assert_called_once() + mock_async_activate_log_queue_handler.reset_mock() + await bootstrap.async_enable_logging( hass, log_rotate_days=5, log_file="test.log", ) mock_async_activate_log_queue_handler.assert_called_once() - # Even on Supervisor, the log file should be created if explicitly set - assert len(glob.glob(arg_log_file_pattern)) > 0 + # Even on Supervisor, the log file should be created if it is explicitly specified + assert len(glob.glob(ARG_LOG_FILE_PATTERN)) > 0 cleanup_log_files() @@ -1689,5 +1715,4 @@ async def test_recorder_not_promoted(hass: HomeAssistant) -> None: for domains in integrations_all_dependencies.values() for domain in domains ) - assert "recorder" not in all_integrations