89 lines
2.6 KiB
Python
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()
|