From 615a655dd8770a916001e261209a7143fc9d00d5 Mon Sep 17 00:00:00 2001 From: Michael Chus Date: Sat, 12 Sep 2026 16:44:33 +0300 Subject: [PATCH] test: cover nvidia bug report inventory parsing --- .../nvidia_bug_report/inventory_test.go | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 internal/parser/vendors/nvidia_bug_report/inventory_test.go diff --git a/internal/parser/vendors/nvidia_bug_report/inventory_test.go b/internal/parser/vendors/nvidia_bug_report/inventory_test.go new file mode 100644 index 0000000..3977a27 --- /dev/null +++ b/internal/parser/vendors/nvidia_bug_report/inventory_test.go @@ -0,0 +1,153 @@ +package nvidia_bug_report + +import ( + "strings" + "testing" + + "git.mchus.pro/mchus/logpile/internal/models" + "git.mchus.pro/mchus/logpile/internal/parser" +) + +func TestParserParseInventorySections(t *testing.T) { + content := `NVIDIA bug report log file +nvidia-bug-report.sh Version: 1 +Date: Fri Dec 12 10:14:49 EST 2025 +System Information + Manufacturer: Acme + Product Name: GPU Server + Version: rev-1 + Serial Number: SYS-1 + UUID: uuid-1 + +Processor Information + Version: NVIDIA Grace CPU + Serial Number: CPU-1 + Core Count: 72 + Thread Count: 144 + Max Speed: 3.2 GHz + Current Speed: 2800 MHz + Status: Populated, Enabled + +Memory Device + Size: 64 GB + Locator: DIMM_A1 + Bank Locator: BANK 0 + Type: DDR5 + Type Detail: Synchronous + Speed: 5600 MT/s + Configured Memory Speed: 5200 MT/s + Manufacturer: Micron + Serial Number: MEM-1 + Part Number: PN-1 + Rank: 2 + +System Power Supply + Location: PSU1 + Name: Power Supply + Manufacturer: Delta + Serial Number: PSU-SN + Model Part Number: DPS-3000 + Revision: 1.0 + Max Power Capacity: 3000 W + Status: Present, OK + +/proc/driver/nvidia/gpus/0000:1a:00.0/information +Model: NVIDIA B200 +IRQ: 42 +GPU UUID: GPU-1 +Video BIOS: 96.00 +Bus Type: PCIe +DMA Size: 47 bits +DMA Mask: 0xffff +Bus Location: 0000:1a:00.0 +Device Minor: 0 +GPU Excluded: No +___ +GPU 00000000:1A:00.0 + Serial Number : GPU-SN +0000:5e:00.0 Ethernet controller [0200]: Mellanox Technologies ConnectX-7 [15b3:101e] + Physical Slot: SLOT-1 + Vital Product Data + Product Name: Dual-port QSFP56 Adapter + [PN] Part number: MCX75310AAS + [SN] Serial number: NIC-1 + [EC] Engineering changes: A1 + End +NVRM version: 570.172.08 +` + + p := &Parser{} + result, err := p.Parse([]parser.ExtractedFile{{Path: "nvidia-bug-report.log", Content: []byte(content)}}) + if err != nil { + t.Fatalf("Parse: %v", err) + } + if result.Hardware.BoardInfo.ProductName != "GPU Server" || result.Hardware.BoardInfo.SerialNumber != "SYS-1" { + t.Fatalf("unexpected board: %+v", result.Hardware.BoardInfo) + } + if len(result.Hardware.CPUs) != 1 || result.Hardware.CPUs[0].Cores != 72 || result.Hardware.CPUs[0].MaxFreqMHz != 3200 { + t.Fatalf("unexpected CPUs: %+v", result.Hardware.CPUs) + } + if len(result.Hardware.Memory) != 1 || result.Hardware.Memory[0].SizeMB != 65536 || result.Hardware.Memory[0].Ranks != 2 { + t.Fatalf("unexpected memory: %+v", result.Hardware.Memory) + } + if len(result.Hardware.PowerSupply) != 1 || !result.Hardware.PowerSupply[0].Present || result.Hardware.PowerSupply[0].WattageW != 3000 { + t.Fatalf("unexpected power supplies: %+v", result.Hardware.PowerSupply) + } + if len(result.Hardware.GPUs) != 1 || result.Hardware.GPUs[0].SerialNumber != "GPU-SN" || result.Hardware.GPUs[0].IRQ != 42 { + t.Fatalf("unexpected GPUs: %+v", result.Hardware.GPUs) + } + if len(result.Hardware.NetworkAdapters) != 1 { + t.Fatalf("unexpected network adapters: %+v", result.Hardware.NetworkAdapters) + } + nic := result.Hardware.NetworkAdapters[0] + if nic.Model != "Dual-port QSFP56 Adapter" || nic.PortCount != 2 || nic.PortType != "QSFP56" || nic.SerialNumber != "NIC-1" { + t.Fatalf("unexpected network adapter: %+v", nic) + } + if !hasEvent(result.Events, "Memory Configuration") || !hasEvent(result.Events, "GPU Detection") || !hasEvent(result.Events, "Driver Version") { + t.Fatalf("expected inventory events, got %+v", result.Events) + } +} + +func TestParserDetectAndScalarParsers(t *testing.T) { + p := &Parser{} + if got := p.Detect([]parser.ExtractedFile{{Path: "nvidia-bug-report.log", Content: []byte("nvidia-bug-report.sh NVIDIA bug report log file")}}); got != 85 { + t.Fatalf("Detect = %d", got) + } + if got := p.Detect(nil); got != 0 { + t.Fatalf("empty Detect = %d", got) + } + if p.Name() == "" || p.Version() == "" { + t.Fatal("expected parser identity") + } + for _, tc := range []struct { + value string + want int + }{ + {"2.5 GHz", 2500}, {"3200 MHz", 3200}, {"bad", 0}, + } { + if got := parseCPUSpeed(tc.value); got != tc.want { + t.Errorf("parseCPUSpeed(%q) = %d, want %d", tc.value, got, tc.want) + } + } + if got := parseMemorySize("2 TB"); got != 2*1024*1024 { + t.Fatalf("parseMemorySize = %d", got) + } + if got := parseMemorySpeed("5600 MT/s"); got != 5600 { + t.Fatalf("parseMemorySpeed = %d", got) + } + if got := parsePowerWattage("1200 Watts"); got != 1200 { + t.Fatalf("parsePowerWattage = %d", got) + } + if got := formatGPUSummary([]models.GPU{{BDF: "0000:1a:00.0", Model: "B200"}}); !strings.Contains(got, "B200") { + t.Fatalf("formatGPUSummary = %q", got) + } +} + +func hasEvent(events []models.Event, eventType string) bool { + for _, event := range events { + if event.EventType == eventType { + return true + } + } + return false +}