87 lines
3.1 KiB
Python
87 lines
3.1 KiB
Python
import _bootstrap # noqa: F401
|
|
|
|
import unittest
|
|
from datetime import datetime, timezone
|
|
|
|
from fault_log_analyzer import models
|
|
|
|
|
|
class TestIsoHelpers(unittest.TestCase):
|
|
def test_to_iso_naive(self):
|
|
dt = datetime(2025, 1, 1, 10, 0, 0)
|
|
self.assertEqual(models.to_iso(dt), "2025-01-01T10:00:00Z")
|
|
|
|
def test_from_iso_z(self):
|
|
dt = models.from_iso("2025-01-01T10:00:00Z")
|
|
self.assertEqual(dt.year, 2025)
|
|
self.assertIsNotNone(dt.tzinfo)
|
|
|
|
def test_from_iso_invalid_returns_none(self):
|
|
self.assertIsNone(models.from_iso("not-a-date"))
|
|
self.assertIsNone(models.from_iso(None))
|
|
self.assertIsNone(models.from_iso(""))
|
|
|
|
|
|
class TestFaultLogRoundTrip(unittest.TestCase):
|
|
def test_roundtrip(self):
|
|
fl = models.FaultLog(
|
|
fault_log_id="fl-1",
|
|
host_id="h-1",
|
|
fingerprint="fp",
|
|
level="ERROR",
|
|
message="disk full",
|
|
occurred_at=datetime(2025, 1, 1, 10, 0, 0, tzinfo=timezone.utc),
|
|
fault_type="disk_full",
|
|
cluster_id="c-1",
|
|
service="app",
|
|
trace_id="t-1",
|
|
count=3,
|
|
)
|
|
d = fl.to_dict()
|
|
fl2 = models.FaultLog.from_dict(d)
|
|
self.assertEqual(fl2.fault_log_id, "fl-1")
|
|
self.assertEqual(fl2.host_id, "h-1")
|
|
self.assertEqual(fl2.count, 3)
|
|
self.assertEqual(fl2.occurred_at.tzinfo is not None, True)
|
|
|
|
|
|
class TestRootCauseRoundTrip(unittest.TestCase):
|
|
def test_roundtrip_with_evidence(self):
|
|
rc = models.RootCause(
|
|
fault_log_id="fl-1",
|
|
cause_type="disk_full",
|
|
confidence=0.92,
|
|
evidence=[
|
|
models.Evidence(type="event", event_id="e-1", metric="disk_used_percent", value=97.2),
|
|
models.Evidence(type="log", message="No space left on device"),
|
|
],
|
|
)
|
|
d = rc.to_dict()
|
|
rc2 = models.RootCause.from_dict(d)
|
|
self.assertEqual(rc2.fault_log_id, "fl-1")
|
|
self.assertEqual(rc2.cause_type, "disk_full")
|
|
self.assertEqual(len(rc2.evidence), 2)
|
|
self.assertEqual(rc2.evidence[0].event_id, "e-1")
|
|
|
|
|
|
class TestOtherModelRoundTrips(unittest.TestCase):
|
|
def test_fault_type(self):
|
|
ft = models.FaultType(fault_type="disk_full", name="磁盘满", pattern="disk full", severity="critical")
|
|
self.assertEqual(models.FaultType.from_dict(ft.to_dict()).fault_type, "disk_full")
|
|
|
|
def test_filter_rule(self):
|
|
r = models.FaultFilterRule(name="disk", level="ERROR", pattern="disk", exclude_pattern="ignore")
|
|
self.assertEqual(models.FaultFilterRule.from_dict(r.to_dict()).pattern, "disk")
|
|
|
|
def test_event(self):
|
|
e = models.Event(event_id="e-1", host_id="h-1", metric="cpu_usage", value=99.0)
|
|
self.assertEqual(models.Event.from_dict(e.to_dict()).value, 99.0)
|
|
|
|
def test_log_entry(self):
|
|
le = models.LogEntry(timestamp=datetime(2025, 1, 1, tzinfo=timezone.utc), level="ERROR", message="x")
|
|
self.assertEqual(models.LogEntry.from_dict(le.to_dict()).message, "x")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|