package collector import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" ) func TestRedfishConnectorCollect(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", map[string]interface{}{"Name": "ServiceRoot"}) register("/redfish/v1/Systems/1", map[string]interface{}{ "Manufacturer": "Supermicro", "Model": "SYS-TEST", "SerialNumber": "SYS123", "BiosVersion": "2.1a", }) register("/redfish/v1/Systems/1/Bios", map[string]interface{}{"Version": "2.1a"}) register("/redfish/v1/Systems/1/SecureBoot", map[string]interface{}{"SecureBootCurrentBoot": "Enabled"}) register("/redfish/v1/Systems/1/Processors", map[string]interface{}{ "Members": []map[string]string{ {"@odata.id": "/redfish/v1/Systems/1/Processors/CPU1"}, }, }) register("/redfish/v1/Systems/1/Processors/CPU1", map[string]interface{}{ "Name": "CPU1", "Model": "Xeon Gold", "TotalCores": 32, "TotalThreads": 64, "MaxSpeedMHz": 3600, }) register("/redfish/v1/Systems/1/Memory", map[string]interface{}{ "Members": []map[string]string{ {"@odata.id": "/redfish/v1/Systems/1/Memory/DIMM1"}, }, }) register("/redfish/v1/Systems/1/Memory/DIMM1", map[string]interface{}{ "Name": "DIMM A1", "CapacityMiB": 32768, "MemoryDeviceType": "DDR5", "OperatingSpeedMhz": 4800, "Status": map[string]interface{}{ "Health": "OK", }, }) register("/redfish/v1/Systems/1/Storage", map[string]interface{}{ "Members": []map[string]string{ {"@odata.id": "/redfish/v1/Systems/1/Storage/1"}, }, }) register("/redfish/v1/Systems/1/Storage/1", map[string]interface{}{ "Drives": []map[string]string{ {"@odata.id": "/redfish/v1/Systems/1/Storage/1/Drives/1"}, }, }) register("/redfish/v1/Systems/1/Storage/1/Drives/1", map[string]interface{}{ "Name": "Drive1", "Model": "NVMe Test", "MediaType": "SSD", "Protocol": "NVMe", "CapacityGB": 960, "SerialNumber": "SN123", }) register("/redfish/v1/Systems/1/PCIeDevices", map[string]interface{}{ "Members": []map[string]string{ {"@odata.id": "/redfish/v1/Systems/1/PCIeDevices/GPU1"}, }, }) register("/redfish/v1/Systems/1/PCIeDevices/GPU1", map[string]interface{}{ "Id": "GPU1", "Name": "NVIDIA H100", "Model": "NVIDIA H100 PCIe", "Manufacturer": "NVIDIA", "SerialNumber": "GPU-SN-001", "PCIeFunctions": map[string]interface{}{ "@odata.id": "/redfish/v1/Systems/1/PCIeDevices/GPU1/PCIeFunctions", }, }) register("/redfish/v1/Systems/1/PCIeDevices/GPU1/PCIeFunctions", map[string]interface{}{ "Members": []map[string]string{ {"@odata.id": "/redfish/v1/Systems/1/PCIeFunctions/GPU1F0"}, }, }) register("/redfish/v1/Systems/1/PCIeFunctions/GPU1F0", map[string]interface{}{ "FunctionId": "0000:65:00.0", "VendorId": "0x10DE", "DeviceId": "0x2331", "ClassCode": "0x030200", "CurrentLinkWidth": 16, "CurrentLinkSpeed": "16.0 GT/s", "MaxLinkWidth": 16, "MaxLinkSpeed": "16.0 GT/s", }) register("/redfish/v1/Chassis/1/NetworkAdapters", map[string]interface{}{ "Members": []map[string]string{ {"@odata.id": "/redfish/v1/Chassis/1/NetworkAdapters/1"}, }, }) register("/redfish/v1/Chassis/1/Power", map[string]interface{}{ "PowerSupplies": []map[string]interface{}{ { "MemberId": "PSU1", "Name": "PSU Slot 1", "Model": "PWS-2K01A-1R", "Manufacturer": "Delta", "PowerCapacityWatts": 2000, "PowerInputWatts": 1600, "LastPowerOutputWatts": 1200, "LineInputVoltage": 230, "Status": map[string]interface{}{ "Health": "OK", "State": "Enabled", }, }, }, }) register("/redfish/v1/Chassis/1/NetworkAdapters/1", map[string]interface{}{ "Name": "Mellanox", "Model": "ConnectX-6", "SerialNumber": "NIC123", }) register("/redfish/v1/Managers/1", map[string]interface{}{ "FirmwareVersion": "1.25", }) register("/redfish/v1/Managers/1/NetworkProtocol", map[string]interface{}{ "Id": "NetworkProtocol", }) ts := httptest.NewServer(mux) defer ts.Close() c := NewRedfishConnector() result, err := c.Collect(context.Background(), Request{ Host: ts.URL, Port: 443, Protocol: "redfish", Username: "admin", AuthType: "password", Password: "secret", TLSMode: "strict", }, nil) if err != nil { t.Fatalf("collect failed: %v", err) } if result.Hardware == nil { t.Fatalf("expected hardware config") } if result.Hardware.BoardInfo.ProductName != "SYS-TEST" { t.Fatalf("unexpected board model: %q", result.Hardware.BoardInfo.ProductName) } if len(result.Hardware.CPUs) != 1 { t.Fatalf("expected one CPU, got %d", len(result.Hardware.CPUs)) } if len(result.Hardware.Memory) != 1 { t.Fatalf("expected one DIMM, got %d", len(result.Hardware.Memory)) } if len(result.Hardware.Storage) != 1 { t.Fatalf("expected one drive, got %d", len(result.Hardware.Storage)) } if len(result.Hardware.NetworkAdapters) != 1 { t.Fatalf("expected one nic, got %d", len(result.Hardware.NetworkAdapters)) } if len(result.Hardware.GPUs) != 1 { t.Fatalf("expected one gpu, got %d", len(result.Hardware.GPUs)) } if result.Hardware.GPUs[0].BDF != "0000:65:00.0" { t.Fatalf("unexpected gpu BDF: %q", result.Hardware.GPUs[0].BDF) } if len(result.Hardware.PCIeDevices) != 1 { t.Fatalf("expected one pcie device, got %d", len(result.Hardware.PCIeDevices)) } if len(result.Hardware.PowerSupply) != 1 { t.Fatalf("expected one psu, got %d", len(result.Hardware.PowerSupply)) } if result.Hardware.PowerSupply[0].WattageW != 2000 { t.Fatalf("unexpected psu wattage: %d", result.Hardware.PowerSupply[0].WattageW) } if len(result.Hardware.Firmware) == 0 { t.Fatalf("expected firmware entries") } if result.RawPayloads == nil { t.Fatalf("expected raw payloads") } treeAny, ok := result.RawPayloads["redfish_tree"] if !ok { t.Fatalf("expected redfish_tree in raw payloads") } tree, ok := treeAny.(map[string]interface{}) if !ok || len(tree) == 0 { t.Fatalf("expected non-empty redfish_tree, got %#v", treeAny) } }