fix(inventory): read GPU model from device field, not vendor field
CI / Lint + build + test (push) Successful in 1m37s
Release / release (push) Successful in 11m43s

`lspci -D -mm -nn` prefixes every line with the PCI address as a bare
token before the three quoted class/vendor/device fields, so the
device name sits at fields[3] — not fields[2], which is the vendor.
The probe was indexing [2] and recording every GPU's model as its
vendor string ("Intel Corporation" instead of "Alder Lake-N [UHD
Graphics]"), which made every SpecValidate mismatch on real hosts
once the expected spec named the device.

Extract the per-line parse into parseLspciMMLine, handle both the
modern -D layout (addr + class/vendor/device) and the legacy
layout without an address prefix (class/vendor/device), and cover
both paths plus the non-GPU-class skip in inventory_test.go.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-19 22:53:42 -04:00
parent e73b221a8c
commit 21014c1268
2 changed files with 92 additions and 32 deletions
+51
View File
@@ -153,6 +153,57 @@ Memory Device
}
}
func TestParseLspciMMLine(t *testing.T) {
cases := []struct {
name string
line string
wantAddr string
wantModel string
wantSkipped bool
}{
{
name: "with -D, N95 integrated GPU",
line: `0000:00:02.0 "VGA compatible controller [0300]" "Intel Corporation [8086]" "Alder Lake-N [UHD Graphics] [46d0]" -r1c "Intel Corporation [8086]" "Device [7270]"`,
wantAddr: "0000:00:02.0",
wantModel: "Alder Lake-N [UHD Graphics]",
},
{
name: "without -D, legacy three-quoted layout",
line: `"VGA compatible controller" "NVIDIA Corporation" "GP104 [GeForce GTX 1080]"`,
wantAddr: "",
wantModel: "GP104 [GeForce GTX 1080]",
},
{
name: "3D controller class also picked up",
line: `0000:01:00.0 "3D controller [0302]" "NVIDIA Corporation [10de]" "TU104GL [Tesla T4] [1eb8]"`,
wantAddr: "0000:01:00.0",
wantModel: "TU104GL [Tesla T4]",
},
{
name: "non-GPU class is skipped",
line: `0000:01:00.0 "Ethernet controller [0200]" "Intel Corporation [8086]" "I350 [1521]"`,
wantSkipped: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
addr, model := parseLspciMMLine(tc.line)
if tc.wantSkipped {
if model != "" {
t.Fatalf("expected skip, got addr=%q model=%q", addr, model)
}
return
}
if addr != tc.wantAddr {
t.Errorf("addr: got %q want %q", addr, tc.wantAddr)
}
if model != tc.wantModel {
t.Errorf("model: got %q want %q", model, tc.wantModel)
}
})
}
}
func TestParseLspciVerbose(t *testing.T) {
sample := `01:00.0 VGA compatible controller: NVIDIA Corporation
Subsystem: ASUSTeK