"""
-------------------------------------------------------------------------
This file is part of the MindStudio project.
Copyright (c) 2025 Huawei Technologies Co.,Ltd.
MindStudio is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
-------------------------------------------------------------------------
"""
"""
msmodelslim.utils.logging 模块的单元测试
"""
import logging
from unittest import TestCase
from msmodelslim.utils.logging import (
logger_setter, get_logger, set_logger_level
)
class TestLoggerSetter(TestCase):
"""测试 logger_setter 装饰器和上下文管理器"""
def test_decorator_when_decorate_function_with_prefix_then_use_specified_logger(self):
"""测试装饰器功能:当装饰函数并指定前缀时,函数内部应使用指定的logger名称"""
@logger_setter(prefix="test.module")
def test_function():
logger = get_logger()
self.assertEqual(logger.name, "test.module")
test_function()
def test_decorator_when_decorate_function_without_prefix_then_use_module_name(self):
"""测试装饰器功能:当装饰函数但不指定前缀时,应使用函数所在模块名作为logger名称"""
@logger_setter()
def test_function():
logger = get_logger()
self.assertIn("test_logging", logger.name)
test_function()
def test_decorator_when_decorate_class_with_prefix_and_subfix_then_all_methods_use_specified_logger(self):
"""测试装饰器功能:当装饰类并指定前缀和后缀时,类的所有方法都应使用指定的logger名称"""
@logger_setter(prefix="test.class", subfix="methods")
class TestClass:
def method1(self):
logger = get_logger()
return logger.name
@staticmethod
def static_method():
logger = get_logger()
return logger.name
@classmethod
def class_method(cls):
logger = get_logger()
return logger.name
obj = TestClass()
self.assertEqual(obj.method1(), "test.class.methods")
self.assertEqual(TestClass.static_method(), "test.class.methods")
self.assertEqual(TestClass.class_method(), "test.class.methods")
def test_context_manager_when_use_with_prefix_then_use_specified_logger_and_restore_after_exit(self):
"""测试上下文管理器功能:使用前缀时应在内部使用指定logger,退出后恢复原始logger"""
original_logger = get_logger()
original_name = original_logger.name
with logger_setter(prefix="test.context"):
logger = get_logger()
self.assertEqual(logger.name, "test.context")
restored_logger = get_logger()
self.assertEqual(restored_logger.name, original_name)
def test_context_manager_when_use_with_prefix_and_subfix_then_use_combined_logger_name(self):
"""测试上下文管理器功能:使用前缀和后缀时logger名称应为prefix.subfix格式"""
original_logger = get_logger()
original_name = original_logger.name
with logger_setter(prefix="test.app", subfix="database"):
logger = get_logger()
self.assertEqual(logger.name, "test.app.database")
restored_logger = get_logger()
self.assertEqual(restored_logger.name, original_name)
def test_context_manager_when_nested_use_then_each_level_has_own_logger_and_restore_correctly(self):
"""测试嵌套上下文管理器:每层应使用自己的logger,退出时正确恢复到上一层的logger"""
original_logger = get_logger()
original_name = original_logger.name
with logger_setter(prefix="outer"):
outer_logger = get_logger()
self.assertEqual(outer_logger.name, "outer")
with logger_setter(prefix="inner", subfix="nested"):
inner_logger = get_logger()
self.assertEqual(inner_logger.name, "inner.nested")
current_logger = get_logger()
self.assertEqual(current_logger.name, "outer")
final_logger = get_logger()
self.assertEqual(final_logger.name, original_name)
def test_context_manager_when_no_prefix_specified_then_use_calling_module_name(self):
"""测试上下文管理器功能:不指定前缀时应使用调用模块名作为logger名称"""
original_logger = get_logger()
original_name = original_logger.name
with logger_setter():
logger = get_logger()
self.assertIn("test_logging", logger.name)
restored_logger = get_logger()
self.assertEqual(restored_logger.name, original_name)
def test_context_manager_when_only_subfix_specified_then_use_calling_module_with_subfix(self):
"""测试上下文管理器功能:只指定后缀时logger名称应为模块名.subfix格式"""
original_logger = get_logger()
original_name = original_logger.name
with logger_setter(subfix="test"):
logger = get_logger()
self.assertTrue(logger.name.endswith(".test"))
restored_logger = get_logger()
self.assertEqual(restored_logger.name, original_name)
def test_decorator_when_specify_prefix_then_use_specified_prefix(self):
"""测试装饰器功能:指定前缀时应使用指定的前缀作为logger名称"""
@logger_setter(prefix="msmodelslim.utils.logging")
def test_function_with_prefix():
logger = get_logger()
self.assertEqual(logger.name, "msmodelslim.utils.logging")
test_function_with_prefix()
def test_decorator_when_specify_subfix_then_use_function_module_with_subfix(self):
"""测试装饰器功能:指定后缀时logger名称应为函数模块名.subfix格式"""
@logger_setter(subfix="custom")
def test_function_with_subfix():
logger = get_logger()
self.assertTrue(logger.name.endswith(".custom"))
test_function_with_subfix()
class TestLoggingFunctions(TestCase):
"""测试其他日志相关函数"""
def test_get_logger_when_no_name_specified_then_return_default_logger(self):
"""测试get_logger函数:不指定名称时应返回默认logger,指定名称时应返回对应名称的logger"""
logger = get_logger()
self.assertIsInstance(logger, logging.Logger)
named_logger = get_logger("test.named")
self.assertIsInstance(named_logger, logging.Logger)
self.assertEqual(named_logger.name, "test.named")
def test_set_logger_level_when_valid_level_then_set_successfully(self):
"""测试set_logger_level函数:设置有效级别时应成功,设置无效级别时应抛出异常"""
set_logger_level("debug")
logger = get_logger()
self.assertEqual(logger.level, logging.DEBUG)
set_logger_level("info")
logger = get_logger()
self.assertEqual(logger.level, logging.INFO)
set_logger_level("warning")
logger = get_logger()
self.assertEqual(logger.level, logging.WARNING)
set_logger_level("error")
logger = get_logger()
self.assertEqual(logger.level, logging.ERROR)
set_logger_level("critical")
logger = get_logger()
self.assertEqual(logger.level, logging.CRITICAL)
with self.assertRaises(Exception):
set_logger_level(123)
if __name__ == "__main__":
import unittest
unittest.main()