# -*- coding: utf-8 -*- """统一日志:文件不可写时降级,首次 emit 不抛 PermissionError。""" from __future__ import annotations import logging import os import tempfile import unittest from logging.handlers import TimedRotatingFileHandler from unittest.mock import patch from jiangchang_skill_core import unified_logging as ul class TestUnifiedLogging(unittest.TestCase): def setUp(self) -> None: ul._skill_slug = "" ul._logger_name = "" def test_can_open_log_file_writable(self) -> None: with tempfile.TemporaryDirectory() as tmp: path = os.path.join(tmp, "test.log") ok, err = ul._can_open_log_file(path) self.assertTrue(ok) self.assertEqual(err, "") self.assertTrue(os.path.isfile(path)) def test_setup_skill_logging_writable(self) -> None: with tempfile.TemporaryDirectory() as tmp: log_path = os.path.join(tmp, "skill.log") logger_name = "test.logger.writable" with patch.object(ul, "get_skill_log_file_path", return_value=log_path): ul.setup_skill_logging("receive-order", logger_name) ul.get_skill_logger().info("hello") self.assertTrue(os.path.isfile(log_path)) ul._clear_logger_handlers(logging.getLogger(logger_name)) def test_setup_skill_logging_unwritable_no_file_handler(self) -> None: logger_name = "test.logger.unwritable" with patch.object(ul, "_can_open_log_file", return_value=(False, "permission denied")): ul.setup_skill_logging("receive-order", logger_name) lg = logging.getLogger(logger_name) lg.info("hello") handlers = logging.getLogger(logger_name).handlers self.assertFalse(any(isinstance(h, TimedRotatingFileHandler) for h in handlers)) self.assertTrue(any(isinstance(h, logging.NullHandler) for h in handlers)) def test_attach_unified_file_handler_unwritable(self) -> None: logger_name = "test.logger.attach.unwritable" with patch.object(ul, "_can_open_log_file", return_value=(False, "permission denied")): lg = ul.attach_unified_file_handler( "/no/access/test.log", skill_slug="receive-order", logger_name=logger_name, ) lg.info("hello") self.assertFalse( any(isinstance(h, logging.FileHandler) for h in lg.handlers) ) self.assertTrue(any(isinstance(h, logging.NullHandler) for h in lg.handlers)) if __name__ == "__main__": unittest.main()