fault-log-analyzer/tests/test_workers.py

89 lines
2.6 KiB
Python

"""聚类与根因分析 worker 测试。"""
import _bootstrap # noqa: F401
import unittest
from datetime import datetime, timezone
from fault_log_analyzer.cluster import Clusterer
from fault_log_analyzer.models import FaultLog
from fault_log_analyzer.storage import MemoryStorage
from fault_log_analyzer.workers import ClusterWorker, RootCauseWorker
BASE = datetime(2025, 1, 1, 10, 0, 0, tzinfo=timezone.utc)
def _logs():
return [
FaultLog(
fault_log_id="fl-1",
host_id="h-1",
message="no space left on device",
level="ERROR",
occurred_at=BASE,
),
FaultLog(
fault_log_id="fl-2",
host_id="h-1",
message="no space left on device /var",
level="ERROR",
occurred_at=BASE,
),
FaultLog(
fault_log_id="fl-3",
host_id="h-1",
message="out of memory error",
level="ERROR",
occurred_at=BASE,
),
]
class TestClusterWorker(unittest.TestCase):
def test_empty(self):
s = MemoryStorage()
self.assertEqual(
ClusterWorker(s).run(), {"clustered": 0, "clusters": 0, "noise": 0}
)
def test_run_clusters_and_classifies(self):
s = MemoryStorage()
for log in _logs():
s.save_fault_log(log)
worker = ClusterWorker(s, clusterer=Clusterer(eps=0.75, min_samples=2))
result = worker.run()
self.assertEqual(result["clustered"], 2)
self.assertGreaterEqual(result["clusters"], 1)
self.assertEqual(result["noise"], 1)
fl1 = s.get_fault_log("fl-1")
self.assertEqual(fl1.fault_type, "disk_full")
self.assertEqual(fl1.cluster_id, "c-0")
self.assertIsNone(s.get_fault_log("fl-3").fault_type)
class TestRootCauseWorker(unittest.TestCase):
def test_empty(self):
s = MemoryStorage()
self.assertEqual(RootCauseWorker(s).run(), [])
def test_analyzes_and_skips_existing(self):
s = MemoryStorage()
log = FaultLog(
fault_log_id="fl-1",
host_id="h-1",
message="no space left on device",
level="ERROR",
occurred_at=BASE,
)
s.save_fault_log(log)
worker = RootCauseWorker(s)
results = worker.run()
self.assertEqual(len(results), 1)
self.assertEqual(results[0].cause_type, "disk_full")
self.assertEqual(s.get_root_cause("fl-1").cause_type, "disk_full")
# 再次运行应跳过已分析日志
self.assertEqual(worker.run(), [])
if __name__ == "__main__":
unittest.main()