"""聚类与根因分析 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()