package collector import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" "time" "git.mchus.pro/mchus/logpile/internal/models" ) func TestCollectRedfishLogEntries_UsesLinkedManagerLogServicesPath(t *testing.T) { mux := http.NewServeMux() register := func(path string, payload interface{}) { mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(payload) }) } register("/redfish/v1/Managers/1", map[string]interface{}{ "Id": "1", "LogServices": map[string]interface{}{ "@odata.id": "/redfish/v1/Systems/1/LogServices", }, }) register("/redfish/v1/Systems/1/LogServices", map[string]interface{}{ "Members": []map[string]string{ {"@odata.id": "/redfish/v1/Systems/1/LogServices/SEL"}, }, }) register("/redfish/v1/Systems/1/LogServices/SEL", map[string]interface{}{ "Id": "SEL", "Entries": map[string]interface{}{ "@odata.id": "/redfish/v1/Systems/1/LogServices/SEL/Entries", }, }) register("/redfish/v1/Systems/1/LogServices/SEL/Entries", map[string]interface{}{ "Members": []map[string]string{ {"@odata.id": "/redfish/v1/Systems/1/LogServices/SEL/Entries/1"}, }, }) register("/redfish/v1/Systems/1/LogServices/SEL/Entries/1", map[string]interface{}{ "Id": "1", "Created": time.Now().UTC().Format(time.RFC3339), "Message": "System found Unqualified DIMM in slot DIMM A1", "MessageSeverity": "OK", "SensorType": "Memory", "EntryType": "Event", }) ts := httptest.NewServer(mux) defer ts.Close() c := NewRedfishConnector() got := c.collectRedfishLogEntries(context.Background(), ts.Client(), Request{ Host: ts.URL, Port: 443, Protocol: "redfish", Username: "admin", AuthType: "password", Password: "secret", TLSMode: "strict", }, ts.URL, nil, []string{"/redfish/v1/Managers/1"}) if len(got) != 1 { t.Fatalf("expected 1 collected log entry, got %d", len(got)) } if got[0]["Message"] != "System found Unqualified DIMM in slot DIMM A1" { t.Fatalf("unexpected collected message: %#v", got[0]["Message"]) } } func TestParseRedfishLogEntries_UnqualifiedDIMMBecomesWarning(t *testing.T) { rawPayloads := map[string]any{ "redfish_log_entries": []any{ map[string]any{ "Id": "sel-1", "Created": "2026-04-13T12:00:00Z", "Message": "System found Unqualified DIMM in slot DIMM A1", "MessageSeverity": "OK", "SensorType": "Memory", "EntryType": "Event", }, }, } events := parseRedfishLogEntries(rawPayloads, time.Date(2026, 4, 13, 12, 30, 0, 0, time.UTC)) if len(events) != 1 { t.Fatalf("expected 1 event, got %d", len(events)) } if events[0].Severity != models.SeverityWarning { t.Fatalf("expected warning severity, got %q", events[0].Severity) } if events[0].Description != "System found Unqualified DIMM in slot DIMM A1" { t.Fatalf("unexpected description: %q", events[0].Description) } } func TestParseRedfishLogEntries_LenovoOEMEntryIsKept(t *testing.T) { rawPayloads := map[string]any{ "redfish_log_entries": []any{ map[string]any{ "Id": "plat-55", "Created": "2026-04-13T12:00:00Z", "Message": "DIMM A1 is unqualified", "MessageSeverity": "Warning", "SensorType": "Memory", "EntryType": "Oem", "OemRecordFormat": "Lenovo", "EntryCode": "Assert", }, }, } events := parseRedfishLogEntries(rawPayloads, time.Date(2026, 4, 13, 12, 30, 0, 0, time.UTC)) if len(events) != 1 { t.Fatalf("expected 1 Lenovo OEM event, got %d", len(events)) } if events[0].Severity != models.SeverityWarning { t.Fatalf("expected warning severity, got %q", events[0].Severity) } }