package inspur import ( "testing" "git.mchus.pro/mchus/logpile/internal/models" ) func TestExtractRedisInlineValue_DecodesHexEncodedString(t *testing.T) { data := []byte("RedisNicInfo:redis_nic_info_t:stNicDeviceInfo0:FWVersion 32362e34332e32353636000000000000\x00tail") key := []byte("RedisNicInfo:redis_nic_info_t:stNicDeviceInfo0:FWVersion") pos := indexBytes(data, key) if pos < 0 { t.Fatal("key not found") } got := extractRedisInlineValue(data, pos+len(key)) if got != "26.43.2566" { t.Fatalf("expected decoded fw 26.43.2566, got %q", got) } } func TestApplyRedisGPUEnrichment_FillsSerialFirmwareUUID(t *testing.T) { hw := &models.HardwareConfig{ GPUs: []models.GPU{ {Slot: "#CPU0_PCIE2", BDF: "0c:00.0", VendorID: 0x10de, Model: "3D Controller"}, {Slot: "#CPU0_PCIE1", BDF: "58:00.0", VendorID: 0x10de, Model: "3D Controller"}, }, } snap := redisGPUSnapshot{ ByIndex: map[int]map[string]string{ 1: { "NV_GPU_SerialNumber": "1321125009572", "NV_GPU_FWVersion": "96.00.B7.00.02", "NV_GPU_UUID": "GPU-AAA", }, 2: { "NV_GPU_SerialNumber": "1321125010420", "NV_GPU_FWVersion": "96.00.B7.00.02", "NV_GPU_UUID": "GPU-BBB", }, }, } applyRedisGPUEnrichment(hw, snap) if hw.GPUs[0].SerialNumber != "1321125009572" || hw.GPUs[0].Firmware != "96.00.B7.00.02" || hw.GPUs[0].UUID != "GPU-AAA" { t.Fatalf("unexpected gpu0 enrichment: %+v", hw.GPUs[0]) } if hw.GPUs[1].SerialNumber != "1321125010420" || hw.GPUs[1].Firmware != "96.00.B7.00.02" || hw.GPUs[1].UUID != "GPU-BBB" { t.Fatalf("unexpected gpu1 enrichment: %+v", hw.GPUs[1]) } } func TestApplyRedisGPUEnrichment_SkipsOnCountMismatch(t *testing.T) { hw := &models.HardwareConfig{ GPUs: []models.GPU{ {Slot: "#CPU0_PCIE2", BDF: "0c:00.0", VendorID: 0x10de, Model: "3D Controller"}, }, } snap := redisGPUSnapshot{ ByIndex: map[int]map[string]string{ 1: {"NV_GPU_SerialNumber": "1321125009572"}, 2: {"NV_GPU_SerialNumber": "1321125010420"}, }, } applyRedisGPUEnrichment(hw, snap) if hw.GPUs[0].SerialNumber != "" { t.Fatalf("expected no enrichment on count mismatch, got %q", hw.GPUs[0].SerialNumber) } } func TestParseRedisRAIDSerials_DecodesHexSerial(t *testing.T) { raw := []byte("RAIDMSCCInfo:redis_pcie_mscc_raid_info_t0:RAIDInfo:SerialNum\x80%@`5341523531314532 \x00tail") got := parseRedisRAIDSerials(raw) if len(got) != 1 { t.Fatalf("expected 1 raid serial, got %d", len(got)) } if got[0] != "SAR511E2" { t.Fatalf("expected decoded serial SAR511E2, got %q", got[0]) } } func TestApplyRedisPCIeEnrichment_FillsStorageControllerSerial(t *testing.T) { hw := &models.HardwareConfig{ PCIeDevices: []models.PCIeDevice{ {Slot: "#CPU1_PCIE9", BDF: "98:00.0", DeviceClass: "Smart Storage PQI SAS", PartNumber: "PM8222-SHBA"}, {Slot: "#CPU0_PCIE3", BDF: "32:00.0", DeviceClass: "Fibre Channel", PartNumber: "LPE32002"}, }, } applyRedisPCIeEnrichment(hw, []string{"SAR511E2"}) if hw.PCIeDevices[0].SerialNumber != "SAR511E2" { t.Fatalf("expected PM8222 serial SAR511E2, got %q", hw.PCIeDevices[0].SerialNumber) } if hw.PCIeDevices[1].SerialNumber != "" { t.Fatalf("expected non-storage device serial untouched, got %q", hw.PCIeDevices[1].SerialNumber) } } func TestParseRedisPCIESerialSnapshot_MapsPNToSN(t *testing.T) { raw := []byte("" + "AssetInfoPCIE:SNPN9:PN PM8222-SHBA\x00" + "AssetInfoPCIE:SNPN9:SN SAR511E2\x00") snap := parseRedisPCIESerialSnapshot(raw) got := snap.ByPart["pm8222-shba"] if got != "SAR511E2" { t.Fatalf("expected SN SAR511E2 for PM8222-SHBA, got %q", got) } } func TestApplyRedisPCIESNPNEnrichment_FillsByPartNumber(t *testing.T) { hw := &models.HardwareConfig{ PCIeDevices: []models.PCIeDevice{ {Slot: "#CPU1_PCIE9", PartNumber: "PM8222-SHBA"}, }, } snap := redisPCIESerialSnapshot{ByPart: map[string]string{"pm8222-shba": "SAR511E2"}} applyRedisPCIESNPNEnrichment(hw, snap) if hw.PCIeDevices[0].SerialNumber != "SAR511E2" { t.Fatalf("expected serial SAR511E2, got %q", hw.PCIeDevices[0].SerialNumber) } } func indexBytes(haystack, needle []byte) int { for i := 0; i+len(needle) <= len(haystack); i++ { match := true for j := 0; j < len(needle); j++ { if haystack[i+j] != needle[j] { match = false break } } if match { return i } } return -1 }