Skip to main content
Glama
test_logger.py9.28 kB
"""日志系统测试""" import pytest import tempfile import os import logging from pathlib import Path from unittest.mock import Mock, patch from ocr_mcp_service.logger import ( MCPLogHandler, OCRLogger, get_logger, initialize_logger, set_mcp_log_level, log_progress, PYTHON_TO_MCP_LEVEL, ) def test_mcp_log_handler_init(): """测试MCPLogHandler初始化""" handler = MCPLogHandler() assert handler.mcp_callback is None assert handler.min_level == logging.INFO def test_mcp_log_handler_set_callback(): """测试设置MCP回调""" handler = MCPLogHandler() callback = Mock() handler.set_mcp_callback(callback) assert handler.mcp_callback == callback def test_mcp_log_handler_set_min_level(): """测试设置最小日志级别""" handler = MCPLogHandler() handler.set_min_level(logging.DEBUG) assert handler.min_level == logging.DEBUG handler.set_min_level(logging.ERROR) assert handler.min_level == logging.ERROR def test_mcp_log_handler_emit_with_callback(): """测试emit方法(有回调)""" callback = Mock() handler = MCPLogHandler(callback) handler.set_min_level(logging.DEBUG) # 创建日志记录 record = logging.LogRecord( name="test_logger", level=logging.INFO, pathname="test.py", lineno=1, msg="test message", args=(), exc_info=None ) handler.emit(record) # 验证回调被调用 callback.assert_called_once() call_args = callback.call_args assert call_args.kwargs["level"] == "info" assert call_args.kwargs["logger"] == "test_logger" assert "message" in call_args.kwargs["data"] def test_mcp_log_handler_emit_level_filter(): """测试emit方法的日志级别过滤""" callback = Mock() handler = MCPLogHandler(callback) handler.set_min_level(logging.WARNING) # DEBUG级别应该被过滤 record_debug = logging.LogRecord( name="test", level=logging.DEBUG, pathname="test.py", lineno=1, msg="debug", args=(), exc_info=None ) handler.emit(record_debug) callback.assert_not_called() # WARNING级别应该通过 record_warning = logging.LogRecord( name="test", level=logging.WARNING, pathname="test.py", lineno=1, msg="warning", args=(), exc_info=None ) handler.emit(record_warning) callback.assert_called_once() def test_mcp_log_handler_emit_extra_fields(): """测试emit方法提取额外字段""" callback = Mock() handler = MCPLogHandler(callback) # 创建带额外字段的记录 record = logging.LogRecord( name="test", level=logging.INFO, pathname="test.py", lineno=1, msg="test", args=(), exc_info=None ) record.progress = 50.0 record.stage = "processing" record.image_path = "/path/to/image.jpg" handler.emit(record) # 验证额外字段被提取 call_args = callback.call_args data = call_args.kwargs["data"] assert data["progress"] == 50.0 assert data["stage"] == "processing" assert data["image_path"] == "/path/to/image.jpg" def test_mcp_log_handler_emit_callback_exception(): """测试emit方法回调异常处理""" def failing_callback(**kwargs): raise Exception("Callback error") handler = MCPLogHandler(failing_callback) record = logging.LogRecord( name="test", level=logging.INFO, pathname="test.py", lineno=1, msg="test", args=(), exc_info=None ) # 应该不会抛出异常 handler.emit(record) def test_ocr_logger_singleton(): """测试OCRLogger单例模式""" # 重置单例状态 OCRLogger._instance = None OCRLogger._initialized = False logger1 = OCRLogger() logger2 = OCRLogger() assert logger1 is logger2 def test_ocr_logger_file_handler(): """测试OCRLogger文件处理器""" with tempfile.TemporaryDirectory() as tmpdir: log_file = os.path.join(tmpdir, "test.log") # 重置单例状态 OCRLogger._instance = None OCRLogger._initialized = False with patch("ocr_mcp_service.logger.get_env") as mock_get_env: mock_get_env.side_effect = lambda key, default: { "LOG_LEVEL": "INFO", "LOG_FILE": log_file, "LOG_MAX_BYTES": "10485760", "LOG_BACKUP_COUNT": "5" }.get(key, default) logger = OCRLogger() test_logger = logger.get_logger("test") test_logger.info("test message") # 关闭所有处理器以释放文件句柄 for handler in logger.logger.handlers: handler.close() # 验证日志文件被创建 assert os.path.exists(log_file) # 验证日志内容 with open(log_file, "r", encoding="utf-8") as f: content = f.read() assert "test message" in content def test_ocr_logger_set_mcp_callback(): """测试OCRLogger设置MCP回调""" OCRLogger._instance = None OCRLogger._initialized = False callback = Mock() logger = OCRLogger() logger.set_mcp_callback(callback) # 验证回调被设置 assert logger.mcp_handler.mcp_callback == callback def test_ocr_logger_set_mcp_log_level(): """测试OCRLogger设置MCP日志级别""" OCRLogger._instance = None OCRLogger._initialized = False logger = OCRLogger() logger.set_mcp_log_level("debug") assert logger.mcp_handler.min_level == logging.DEBUG logger.set_mcp_log_level("error") assert logger.mcp_handler.min_level == logging.ERROR def test_ocr_logger_get_logger(): """测试OCRLogger获取logger""" OCRLogger._instance = None OCRLogger._initialized = False logger = OCRLogger() test_logger = logger.get_logger("test_module") assert test_logger is not None assert test_logger.name == "ocr_mcp_service.test_module" def test_ocr_logger_log_progress(): """测试OCRLogger进度日志""" OCRLogger._instance = None OCRLogger._initialized = False callback = Mock() logger = OCRLogger() logger.set_mcp_callback(callback) logger.log_progress("test", 50.0, "Processing", stage="ocr") # 验证回调被调用 callback.assert_called() call_args = callback.call_args data = call_args.kwargs["data"] assert data["progress"] == 50.0 assert data["stage"] == "ocr" def test_get_logger_function(): """测试get_logger模块级函数""" # 重置全局实例 import ocr_mcp_service.logger as logger_module logger_module._logger_instance = None test_logger = get_logger("test") assert test_logger is not None # 再次调用应该返回同一个实例 test_logger2 = get_logger("test") assert test_logger2 is not None def test_initialize_logger(): """测试initialize_logger函数""" import ocr_mcp_service.logger as logger_module logger_module._logger_instance = None callback = Mock() initialize_logger(callback) # 验证回调被设置 assert logger_module._logger_instance is not None assert logger_module._logger_instance.mcp_handler.mcp_callback == callback def test_set_mcp_log_level_function(): """测试set_mcp_log_level模块级函数""" import ocr_mcp_service.logger as logger_module logger_module._logger_instance = None set_mcp_log_level("warning") # 验证级别被设置 assert logger_module._logger_instance is not None assert logger_module._logger_instance.mcp_handler.min_level == logging.WARNING def test_log_progress_function(): """测试log_progress模块级函数""" import ocr_mcp_service.logger as logger_module # 重置单例状态 logger_module._logger_instance = None OCRLogger._instance = None OCRLogger._initialized = False callback = Mock() initialize_logger(callback) # 验证回调已设置 assert logger_module._logger_instance is not None assert logger_module._logger_instance.mcp_handler.mcp_callback == callback log_progress("test", 75.0, "Almost done", stage="final") # 验证回调被调用(通过MCPLogHandler的emit方法) # 回调是通过logger.info() -> handler.emit() -> callback()调用的 assert callback.called, "MCP callback should be called via handler.emit()" # 验证回调参数 if callback.called: call_args = callback.call_args assert call_args.kwargs["level"] in ["info", "debug", "warning", "error"] data = call_args.kwargs["data"] assert data["progress"] == 75.0 assert data["stage"] == "final" def test_python_to_mcp_level_mapping(): """测试Python到MCP日志级别映射""" assert PYTHON_TO_MCP_LEVEL[logging.DEBUG] == "debug" assert PYTHON_TO_MCP_LEVEL[logging.INFO] == "info" assert PYTHON_TO_MCP_LEVEL[logging.WARNING] == "warning" assert PYTHON_TO_MCP_LEVEL[logging.ERROR] == "error" assert PYTHON_TO_MCP_LEVEL[logging.CRITICAL] == "critical"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/qiao-925/ocr-mcp-service'

If you have feedback or need assistance with the MCP directory API, please join our Discord server