"""监控测试:权限系统监控功能验证 测试权限系统的监控功能,包括: - 指标收集 - 告警生成 - 健康检查 """ import time import uuid import pytest from app.core.permission_monitor import ( PermissionMonitor, PermissionCheckMetrics, CacheMetrics, get_permission_monitor, set_permission_monitor, ) @pytest.mark.asyncio async def test_permission_check_metrics(): """测试权限检查指标""" monitor = PermissionMonitor() # 记录权限检查 monitor.record_permission_check(allowed=True, elapsed_time=0.005) monitor.record_permission_check(allowed=False, elapsed_time=0.003) monitor.record_permission_check(allowed=True, elapsed_time=0.004) metrics = monitor.metrics.check_metrics assert metrics.total_checks == 3 assert metrics.allowed_checks == 2 assert metrics.denied_checks == 1 assert metrics.allow_rate == pytest.approx(66.67, 0.1) assert metrics.deny_rate == pytest.approx(33.33, 0.1) @pytest.mark.asyncio async def test_permission_check_timing(): """测试权限检查耗时统计""" monitor = PermissionMonitor() # 记录不同耗时的权限检查 monitor.record_permission_check(allowed=True, elapsed_time=0.001) monitor.record_permission_check(allowed=True, elapsed_time=0.005) monitor.record_permission_check(allowed=True, elapsed_time=0.003) metrics = monitor.metrics.check_metrics assert metrics.min_time == pytest.approx(0.001, 0.0001) assert metrics.max_time == pytest.approx(0.005, 0.0001) assert metrics.avg_time == pytest.approx(0.003, 0.0001) @pytest.mark.asyncio async def test_cache_metrics(): """测试缓存指标""" monitor = PermissionMonitor() # 记录缓存访问 monitor.record_cache_hit() monitor.record_cache_hit() monitor.record_cache_miss() monitor.record_cache_hit() metrics = monitor.metrics.cache_metrics assert metrics.total_accesses == 4 assert metrics.cache_hits == 3 assert metrics.cache_misses == 1 assert metrics.hit_rate == pytest.approx(75.0, 0.1) assert metrics.miss_rate == pytest.approx(25.0, 0.1) @pytest.mark.asyncio async def test_cache_invalidation_tracking(): """测试缓存失效追踪""" monitor = PermissionMonitor() # 记录缓存失效 monitor.record_cache_invalidation() monitor.record_cache_invalidation() monitor.record_cache_invalidation() metrics = monitor.metrics.cache_metrics assert metrics.cache_invalidations == 3 @pytest.mark.asyncio async def test_error_tracking(): """测试错误追踪""" monitor = PermissionMonitor() # 记录权限检查错误 error = ValueError("test error") monitor.record_permission_check(allowed=False, elapsed_time=0.005, error=error) monitor.record_permission_check(allowed=True, elapsed_time=0.003) metrics = monitor.metrics.check_metrics assert metrics.errors == 1 assert metrics.error_rate == pytest.approx(50.0, 0.1) @pytest.mark.asyncio async def test_alert_generation(): """测试告警生成""" monitor = PermissionMonitor() # 记录慢速权限检查(应该生成告警) monitor.record_permission_check(allowed=True, elapsed_time=0.1) alerts = monitor.get_alerts() assert len(alerts) > 0 assert alerts[0]["type"] == "slow_permission_check" @pytest.mark.asyncio async def test_error_alert_generation(): """测试错误告警生成""" monitor = PermissionMonitor() # 记录权限检查错误(应该生成告警) error = ValueError("test error") monitor.record_permission_check(allowed=False, elapsed_time=0.005, error=error) alerts = monitor.get_alerts() assert len(alerts) > 0 assert alerts[0]["type"] == "permission_check_error" @pytest.mark.asyncio async def test_alert_filtering(): """测试告警过滤""" monitor = PermissionMonitor() # 生成不同级别的告警 monitor.record_permission_check(allowed=True, elapsed_time=0.1) # warning error = ValueError("test error") monitor.record_permission_check(allowed=False, elapsed_time=0.005, error=error) # error # 过滤 warning 级别的告警 warning_alerts = monitor.get_alerts(level="warning") assert len(warning_alerts) > 0 assert all(a["level"] == "warning" for a in warning_alerts) # 过滤 error 级别的告警 error_alerts = monitor.get_alerts(level="error") assert len(error_alerts) > 0 assert all(a["level"] == "error" for a in error_alerts) @pytest.mark.asyncio async def test_alert_limit(): """测试告警数量限制""" monitor = PermissionMonitor() # 生成大量告警 for _ in range(50): monitor.record_permission_check(allowed=True, elapsed_time=0.1) # 获取告警,限制为10条 alerts = monitor.get_alerts(limit=10) assert len(alerts) == 10 @pytest.mark.asyncio async def test_metrics_reset(): """测试指标重置""" monitor = PermissionMonitor() # 记录一些指标 monitor.record_permission_check(allowed=True, elapsed_time=0.005) monitor.record_cache_hit() assert monitor.metrics.check_metrics.total_checks == 1 assert monitor.metrics.cache_metrics.total_accesses == 1 # 重置指标 monitor.reset_metrics() assert monitor.metrics.check_metrics.total_checks == 0 assert monitor.metrics.cache_metrics.total_accesses == 0 @pytest.mark.asyncio async def test_alerts_clear(): """测试告警清除""" monitor = PermissionMonitor() # 生成告警 monitor.record_permission_check(allowed=True, elapsed_time=0.1) assert len(monitor.get_alerts()) > 0 # 清除告警 monitor.clear_alerts() assert len(monitor.get_alerts()) == 0 @pytest.mark.asyncio async def test_metrics_to_dict(): """测试指标转换为字典""" monitor = PermissionMonitor() # 记录指标 monitor.record_permission_check(allowed=True, elapsed_time=0.005) monitor.record_permission_check(allowed=False, elapsed_time=0.003) monitor.record_cache_hit() monitor.record_cache_miss() metrics_dict = monitor.get_metrics() assert "check_metrics" in metrics_dict assert "cache_metrics" in metrics_dict assert "uptime_seconds" in metrics_dict check_metrics = metrics_dict["check_metrics"] assert check_metrics["total_checks"] == 2 assert check_metrics["allowed_checks"] == 1 assert check_metrics["denied_checks"] == 1 cache_metrics = metrics_dict["cache_metrics"] assert cache_metrics["total_accesses"] == 2 assert cache_metrics["cache_hits"] == 1 assert cache_metrics["cache_misses"] == 1 @pytest.mark.asyncio async def test_global_monitor_instance(): """测试全局监控器实例""" monitor1 = get_permission_monitor() monitor2 = get_permission_monitor() # 应该是同一个实例 assert monitor1 is monitor2 @pytest.mark.asyncio async def test_set_global_monitor(): """测试设置全局监控器实例""" new_monitor = PermissionMonitor() set_permission_monitor(new_monitor) monitor = get_permission_monitor() assert monitor is new_monitor @pytest.mark.asyncio async def test_alert_timestamp(): """测试告警时间戳""" monitor = PermissionMonitor() before_time = time.time() monitor.record_permission_check(allowed=True, elapsed_time=0.1) after_time = time.time() alerts = monitor.get_alerts() assert len(alerts) > 0 assert before_time <= alerts[0]["timestamp"] <= after_time @pytest.mark.asyncio async def test_alert_data(): """测试告警数据""" monitor = PermissionMonitor() # 记录慢速权限检查 monitor.record_permission_check(allowed=True, elapsed_time=0.1) alerts = monitor.get_alerts() assert len(alerts) > 0 assert "data" in alerts[0] assert "elapsed_time" in alerts[0]["data"] @pytest.mark.asyncio async def test_permission_check_metrics_dataclass(): """测试权限检查指标数据类""" metrics = PermissionCheckMetrics() # 初始状态 assert metrics.total_checks == 0 assert metrics.avg_time == 0.0 assert metrics.allow_rate == 0.0 # 添加数据 metrics.total_checks = 100 metrics.allowed_checks = 80 metrics.denied_checks = 20 metrics.total_time = 0.5 assert metrics.avg_time == pytest.approx(0.005, 0.0001) assert metrics.allow_rate == pytest.approx(80.0, 0.1) assert metrics.deny_rate == pytest.approx(20.0, 0.1) @pytest.mark.asyncio async def test_cache_metrics_dataclass(): """测试缓存指标数据类""" metrics = CacheMetrics() # 初始状态 assert metrics.total_accesses == 0 assert metrics.hit_rate == 0.0 # 添加数据 metrics.total_accesses = 100 metrics.cache_hits = 80 metrics.cache_misses = 20 assert metrics.hit_rate == pytest.approx(80.0, 0.1) assert metrics.miss_rate == pytest.approx(20.0, 0.1)