package inspur import ( "testing" "time" "git.mchus.pro/mchus/logpile/internal/models" "git.mchus.pro/mchus/logpile/internal/parser" ) func TestDedupSELEvents(t *testing.T) { ts := time.Date(2026, 7, 27, 4, 52, 55, 0, time.UTC) events := []models.Event{ {Source: "BMC", Timestamp: ts, EventType: "Assert", Severity: models.SeverityCritical, Description: "Sys_Health Transition to Critical from less severe"}, {Source: "SEL", Timestamp: ts, EventType: "Transition to Critical from less severe", Severity: models.SeverityCritical, Description: "Transition to Critical from less severe", RawData: "Asserted"}, {Source: "SEL", Timestamp: ts.Add(time.Second), EventType: "Asserted", Description: "PSU0 fail"}, {Source: "SEL", Timestamp: ts.Add(time.Second), EventType: "Asserted", Description: "PSU0 fail"}, {Source: "BMC", Timestamp: ts.Add(2 * time.Second), EventType: "Assert", Description: "recurring alarm"}, {Source: "BMC", Timestamp: ts.Add(2 * time.Second), EventType: "Assert", Description: "recurring alarm"}, } out := dedupSELEvents(events) if len(out) != 4 { t.Fatalf("expected IDL/SEL copy and exact SEL copy removed, recurring BMC alarms retained; got %d: %+v", len(out), out) } if out[0].Source != "BMC" { t.Fatalf("expected richer IDL/BMC event to be retained, got %+v", out[0]) } } func TestParseSELListWithLocation_UsesProvidedTimezone(t *testing.T) { content := []byte("sel elist:\n1,02/28/2026,04:18:18,Sensor X,Event,Asserted\n") shanghai, err := time.LoadLocation("Asia/Shanghai") if err != nil { t.Fatalf("load location: %v", err) } events := ParseSELListWithLocation(content, shanghai) if len(events) != 1 { t.Fatalf("expected 1 event, got %d", len(events)) } // 04:18:18 +08:00 == 20:18:18Z (previous day) want := time.Date(2026, 2, 27, 20, 18, 18, 0, time.UTC) if !events[0].Timestamp.UTC().Equal(want) { t.Fatalf("unexpected timestamp: got %s want %s", events[0].Timestamp.UTC(), want) } } func TestParseTimezoneConfigLocation(t *testing.T) { content := []byte("[TimeZoneConfig]\ntimezone=Asia/Shanghai\n") got := parseTimezoneConfigLocation(content) if got != "Asia/Shanghai" { t.Fatalf("unexpected timezone: %q", got) } } func TestSELTimezoneResolverUsesExplicitOffsetTimeline(t *testing.T) { files := []parser.ExtractedFile{ {Path: "onekeylog/configuration/conf/timezone.conf", Content: []byte("[TimeZoneConfig]\ntimezone=Asia/Shanghai\n")}, {Path: "onekeylog/log/syslog/idl.log", Content: []byte( "|2026-01-30T14:25:14+08:00|BMC|Assert|Info|1|old timezone|\n" + "|2026-07-24T02:20:38+03:00|BMC|Assert|Critical|2|new timezone|\n")}, } fallback := inferInspurArchiveLocation(files) resolver := inferInspurTimezoneResolver(files, fallback) events := parseSELListWithResolver([]byte("sel elist:\n"+ "1,01/30/2026,14:25:14,Chassis Sys_Health,old timezone,Asserted\n"+ "2,07/24/2026,02:20:38,Chassis Sys_Health,new timezone,Asserted\n"), resolver) if len(events) != 2 { t.Fatalf("expected 2 events, got %d", len(events)) } wantOld := time.Date(2026, 1, 30, 6, 25, 14, 0, time.UTC) wantNew := time.Date(2026, 7, 23, 23, 20, 38, 0, time.UTC) if !events[0].Timestamp.UTC().Equal(wantOld) || !events[1].Timestamp.UTC().Equal(wantNew) { t.Fatalf("unexpected resolved timestamps: got %s and %s", events[0].Timestamp.UTC(), events[1].Timestamp.UTC()) } } func TestDetermineSELSeverityDeassertedFaultIsInfo(t *testing.T) { got := determineSELSeverity("Power Supply PSU0", "Failure detected", "Deasserted") if got != models.SeverityInfo { t.Fatalf("expected cleared fault to be info, got %q", got) } }