Older AMI-BMC Inspur onekeylog archives (NF5466M5 / NF5280M5 generation)
opened to an empty result: they carry none of the files the inspur parser
keys on (no asset.json, devicefrusdr.log, selelist.csv or component.log).
New package internal/parser/vendors/inspur_legacy (vendor id inspur_legacy),
separate from inspur:
- binary IPMI FRU decode (FRU.bin) -> board identity
- Inspur_AssetInfoInventory.log -> CPU / memory / PCIe / PSU inventory
- events from Inspur_<model>_<serial>_IDL, sel.log, blackbox.log,
MegaRAID raid0.log, and the flat AMI <severity>.log files
- no live sensors in this archive class -> recorded as a collection error
- BMC clock timestamps before 2010 dropped as un-set (1970 / ~2005 RTC)
Registry: add optional PrioritizedParser { DetectPriority() int } so a
confidence tie is broken by specificity. inspur_legacy returns 10 and also
declines (Detect 0) when modern Kaytus markers are present, so the two
Inspur parsers never fight over a newer dump.
Docs: ADL-065, 06-parsers.md, releases/v1.32.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017VL8wLGD6Lnp6hZCpqT6cZ
86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
package inspurlegacy
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.mchus.pro/mchus/logpile/internal/parser"
|
|
)
|
|
|
|
func f(path string, content string) parser.ExtractedFile {
|
|
return parser.ExtractedFile{Path: path, Content: []byte(content)}
|
|
}
|
|
|
|
func TestDetect_LegacyOnekeylog(t *testing.T) {
|
|
p := &Parser{}
|
|
files := []parser.ExtractedFile{
|
|
f("onekeylog/Inspur_AssetInfoInventory.log", sampleAssetInventory),
|
|
f("onekeylog/Inspur_NF5466M5_221353113_IDL", "2026-05-23T08:16:41|PSU|Critical|Asssert|080053F2|x"),
|
|
f("onekeylog/FRU.bin", ""),
|
|
f("onekeylog/blackbox.log", ""),
|
|
f("onekeylog/sel.log", ""),
|
|
}
|
|
if got := p.Detect(files); got < 80 {
|
|
t.Fatalf("confidence = %d, want high", got)
|
|
}
|
|
}
|
|
|
|
func TestDetect_DisqualifiedByModernMarkers(t *testing.T) {
|
|
p := &Parser{}
|
|
files := []parser.ExtractedFile{
|
|
f("onekeylog/Inspur_AssetInfoInventory.log", ""),
|
|
f("onekeylog/devicefrusdr.log", ""),
|
|
}
|
|
if got := p.Detect(files); got != 0 {
|
|
t.Fatalf("confidence = %d, want 0 (modern Kaytus dump)", got)
|
|
}
|
|
}
|
|
|
|
func TestDetect_UnrelatedArchive(t *testing.T) {
|
|
p := &Parser{}
|
|
files := []parser.ExtractedFile{f("dump/redfish/Systems.json", "{}")}
|
|
if got := p.Detect(files); got != 0 {
|
|
t.Fatalf("confidence = %d, want 0", got)
|
|
}
|
|
}
|
|
|
|
func TestParse_EndToEnd(t *testing.T) {
|
|
p := &Parser{}
|
|
files := []parser.ExtractedFile{
|
|
f("onekeylog/FRU.bin", string(buildFRU())),
|
|
f("onekeylog/Inspur_AssetInfoInventory.log", sampleAssetInventory),
|
|
f("onekeylog/Inspur_NF5466M5_221353113_IDL",
|
|
"2026-05-23T08:16:41|PSU|Critical|Asssert|080053F2|PSU0 unit input off.."),
|
|
f("onekeylog/sel.log",
|
|
" e34 | 05/23/2026 | 08:16:41 | Power Supply PSU0_Status | Power Supply AC lost | Asserted"),
|
|
f("onekeylog/warning.log",
|
|
"<27> 2026-07-09T02:29:25.700000+03:00 localhost dhcp6c[957]: client6_send: transmit failed"),
|
|
}
|
|
|
|
res, err := p.Parse(files)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if res.Hardware.BoardInfo.SerialNumber != "221353113" {
|
|
t.Errorf("board serial = %q", res.Hardware.BoardInfo.SerialNumber)
|
|
}
|
|
if len(res.FRU) != 1 {
|
|
t.Errorf("fru = %d", len(res.FRU))
|
|
}
|
|
if len(res.Hardware.CPUs) != 2 || len(res.Hardware.PowerSupply) != 1 {
|
|
t.Errorf("hw cpus=%d psu=%d", len(res.Hardware.CPUs), len(res.Hardware.PowerSupply))
|
|
}
|
|
if len(res.Events) < 3 {
|
|
t.Errorf("events = %d", len(res.Events))
|
|
}
|
|
// Sensors are legitimately empty for this archive class; the reason is recorded.
|
|
var haveSensorNote bool
|
|
for _, ce := range res.CollectionErrors {
|
|
if ce.Section == "sensors" {
|
|
haveSensorNote = true
|
|
}
|
|
}
|
|
if !haveSensorNote {
|
|
t.Error("missing sensors collection-error note")
|
|
}
|
|
}
|