from __future__ import annotations import logging from pathlib import Path import sys import tempfile import unittest SRC_ROOT = Path(__file__).resolve().parents[2] / "src" if str(SRC_ROOT) not in sys.path: sys.path.insert(0, str(SRC_ROOT)) from ffx.logging_utils import ( # noqa: E402 CONSOLE_HANDLER_NAME, FILE_HANDLER_NAME, MUTED_CONSOLE_LEVEL, configure_ffx_logger, get_ffx_logger, set_ffx_console_logging_enabled, ) class LoggingUtilsTests(unittest.TestCase): def cleanup_logger(self, logger_name: str) -> None: logger = logging.getLogger(logger_name) for handler in list(logger.handlers): logger.removeHandler(handler) handler.close() def test_get_ffx_logger_adds_only_one_null_handler(self): logger_name = "ffx-test-null-handler" self.cleanup_logger(logger_name) logger = get_ffx_logger(logger_name) logger = get_ffx_logger(logger_name) null_handlers = [ handler for handler in logger.handlers if isinstance(handler, logging.NullHandler) ] self.assertEqual(1, len(null_handlers)) self.cleanup_logger(logger_name) def test_configure_ffx_logger_reuses_named_handlers(self): logger_name = "ffx-test-configure-handler" self.cleanup_logger(logger_name) with tempfile.TemporaryDirectory() as tempdir: first_log_path = Path(tempdir) / "first.log" second_log_path = Path(tempdir) / "second.log" logger = configure_ffx_logger( str(first_log_path), logging.ERROR, logging.INFO, name=logger_name, ) logger = configure_ffx_logger( str(second_log_path), logging.DEBUG, logging.WARNING, name=logger_name, ) console_handlers = [ handler for handler in logger.handlers if handler.get_name() == CONSOLE_HANDLER_NAME ] file_handlers = [ handler for handler in logger.handlers if handler.get_name() == FILE_HANDLER_NAME ] self.assertEqual(1, len(console_handlers)) self.assertEqual(1, len(file_handlers)) self.assertFalse( any(isinstance(handler, logging.NullHandler) for handler in logger.handlers) ) self.assertEqual(logging.WARNING, console_handlers[0].level) self.assertEqual(logging.DEBUG, file_handlers[0].level) self.assertEqual(str(second_log_path.resolve()), file_handlers[0].baseFilename) self.cleanup_logger(logger_name) def test_set_ffx_console_logging_enabled_mutes_and_restores_console_handler(self): logger_name = "ffx-test-console-mute" self.cleanup_logger(logger_name) with tempfile.TemporaryDirectory() as tempdir: log_path = Path(tempdir) / "ffx.log" logger = configure_ffx_logger( str(log_path), logging.DEBUG, logging.INFO, name=logger_name, ) console_handler = next( handler for handler in logger.handlers if handler.get_name() == CONSOLE_HANDLER_NAME ) self.assertEqual(logging.INFO, console_handler.level) set_ffx_console_logging_enabled(logger, enabled=False) self.assertEqual(MUTED_CONSOLE_LEVEL, console_handler.level) set_ffx_console_logging_enabled(logger, enabled=True) self.assertEqual(logging.INFO, console_handler.level) self.cleanup_logger(logger_name) if __name__ == "__main__": unittest.main()