nvidia-bug-report.sh appends .gz to --output-file when gzip is available, which silently produced empty nvidia-bug-report.txt in support bundles (cat looked for the uncompressed name that never existed). Also: a GPU that falls off the PCIe/NVLink bus (Xid 79) or gets flagged for Node Reboot Required (Xid 154) mid-SAT-run left every downstream test failing with generic, unrelated-looking errors (CUDA "unknown error", "unable to determine device handle") with no indication the GPU needed a physical power-cycle to recover. Detect these codes from SAT run logs and surface a plain-English "physical reboot required" message in the task's failure detail, the persisted component-status DB, a dashboard banner on the Hardware Summary card, and topology diagram GPU-node severity. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
55 lines
1.3 KiB
Go
55 lines
1.3 KiB
Go
package collector
|
|
|
|
import "testing"
|
|
|
|
func TestXidSeverity(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
line string
|
|
wantSev string
|
|
wantOK bool
|
|
}{
|
|
{
|
|
name: "xid 64 remap write failure is critical",
|
|
line: "NVRM: Xid (PCI:0000:65:00): 64, pid=1234, name=python, Row Remapper: New row remapping failed",
|
|
wantSev: "critical",
|
|
wantOK: true,
|
|
},
|
|
{
|
|
name: "xid 48 uncorrectable ecc is critical",
|
|
line: "NVRM: Xid (PCI:0000:65:00): 48, pid=1234, name=python",
|
|
wantSev: "critical",
|
|
wantOK: true,
|
|
},
|
|
{
|
|
name: "xid 63 remap committed is warning",
|
|
line: "NVRM: Xid (PCI:0000:65:00): 63, pid=1234, Class 0x90a0",
|
|
wantSev: "warning",
|
|
wantOK: true,
|
|
},
|
|
{
|
|
name: "xid 79 GPU fell off the bus is critical",
|
|
line: "NVRM: Xid (PCI:0000:65:00): 79, pid=1234, GPU has fallen off the bus",
|
|
wantSev: "critical",
|
|
wantOK: true,
|
|
},
|
|
{
|
|
name: "no xid in line",
|
|
line: "NVRM: GPU 0000:65:00.0: RmInitAdapter failed",
|
|
wantOK: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
sev, ok := XidSeverity(tt.line)
|
|
if ok != tt.wantOK {
|
|
t.Fatalf("ok: got %v, want %v", ok, tt.wantOK)
|
|
}
|
|
if ok && sev != tt.wantSev {
|
|
t.Fatalf("severity: got %q, want %q", sev, tt.wantSev)
|
|
}
|
|
})
|
|
}
|
|
}
|