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
116 lines
4.1 KiB
Go
116 lines
4.1 KiB
Go
package inspurlegacy
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.mchus.pro/mchus/logpile/internal/models"
|
|
)
|
|
|
|
func TestParseIDLEvents(t *testing.T) {
|
|
in := `1970-01-01T08:00:17|BIOS BOOT|Info|Asssert|1FFF06F0|OS Event System boot completed - boot device not specified
|
|
2026-05-23T08:16:41|PSU|Critical|Asssert|080053F2|PSU0 unit input off for insufficient input voltage..
|
|
2026-08-31T17:14:42|PCIE|Warning|Asssert|17FF01F1|Disk error Predictive Failure asserted
|
|
`
|
|
events := ParseIDLEvents([]byte(in))
|
|
if len(events) != 2 {
|
|
t.Fatalf("events = %d (1970 line must be dropped)", len(events))
|
|
}
|
|
if events[0].Severity != models.SeverityCritical || events[0].SensorName != "PSU" {
|
|
t.Errorf("event0 = %+v", events[0])
|
|
}
|
|
if events[0].Description != "PSU0 unit input off for insufficient input voltage" {
|
|
t.Errorf("trailing dots not trimmed: %q", events[0].Description)
|
|
}
|
|
if events[1].Severity != models.SeverityWarning {
|
|
t.Errorf("event1 severity = %s", events[1].Severity)
|
|
}
|
|
}
|
|
|
|
func TestParseSELLog(t *testing.T) {
|
|
in := ` f | Pre-Init Time-stamp | Button Power_Button | Power Button pressed | Asserted
|
|
e34 | 05/23/2026 | 08:16:41 | Power Supply PSU0_Status | Power Supply AC lost | Asserted
|
|
e36 | 05/23/2026 | 16:28:35 | Power Supply PSU0_Status | Power Supply AC lost | Deasserted
|
|
e45 | 08/31/2026 | 17:14:42 | Add-in Card RAID0_Status | Predictive Failure Asserted
|
|
`
|
|
events := ParseSELLog([]byte(in))
|
|
if len(events) != 3 {
|
|
t.Fatalf("events = %d (pre-init line must be skipped)", len(events))
|
|
}
|
|
if events[0].Severity != models.SeverityCritical {
|
|
t.Errorf("AC lost assert should be critical: %+v", events[0])
|
|
}
|
|
if events[1].Severity != models.SeverityInfo {
|
|
t.Errorf("deassert should be info: %+v", events[1])
|
|
}
|
|
if events[2].Severity != models.SeverityWarning {
|
|
t.Errorf("predictive failure should be warning: %+v", events[2])
|
|
}
|
|
}
|
|
|
|
func TestParseBlackbox(t *testing.T) {
|
|
in := `[1970-01-01 08:00:16] : [*]Power restore after AC power on.
|
|
[2026-05-23 08:16:41] : PSU-0 Fault: Input Under Voltage Protection, StatusWord=0x2848
|
|
`
|
|
events := ParseBlackbox([]byte(in))
|
|
if len(events) != 1 {
|
|
t.Fatalf("events = %d", len(events))
|
|
}
|
|
if events[0].Severity != models.SeverityCritical || events[0].SensorName != "PSU-0" {
|
|
t.Errorf("event = %+v", events[0])
|
|
}
|
|
}
|
|
|
|
func TestParseMegaRAIDLog(t *testing.T) {
|
|
in := `Event Sequence Number : 47100
|
|
Timestamp : 8/31/2026 ; 11:30:49
|
|
Event code : 93
|
|
Locale : PD event
|
|
Class : Information
|
|
Description of the event : Patrol Read corrected medium error on PD 16(e0x2e/s37) at 3a0e3b4a0
|
|
|
|
Event Sequence Number : 47200
|
|
Timestamp : 466920 Seconds
|
|
Class : Information
|
|
Description of the event : Controller cache discarded
|
|
`
|
|
events := ParseMegaRAIDLog([]byte(in), "raid0.log")
|
|
if len(events) != 1 {
|
|
t.Fatalf("events = %d (non-wall-clock timestamp must be dropped)", len(events))
|
|
}
|
|
if events[0].Severity != models.SeverityWarning {
|
|
t.Errorf("medium error should escalate to warning: %+v", events[0])
|
|
}
|
|
if events[0].Source != "RAID/raid0" {
|
|
t.Errorf("source = %q", events[0].Source)
|
|
}
|
|
}
|
|
|
|
func TestParseAMISyslog(t *testing.T) {
|
|
in := `<1> 1970-01-01T08:01:08.130000+08:00 localhost kernel: [ 6.350000] Helper Module Driver Version 1.2
|
|
<9> 2026-03-03T09:10:00.000000+03:00 localhost IPMIMain: CPU0 changed from NULL to Xeon
|
|
<27> 2026-07-09T02:29:25.700000+03:00 localhost dhcp6c[957]: client6_send: transmit failed: Network is unreachable
|
|
<3> 2026-07-09T03:02:02.330000+03:00 localhost kernel: i2c i2c-4: send_bytes: Timed out sending data
|
|
`
|
|
events := ParseAMISyslog([]byte(in), "err.log")
|
|
if len(events) != 3 {
|
|
t.Fatalf("events = %d (1970 line dropped)", len(events))
|
|
}
|
|
if events[0].Severity != models.SeverityInfo {
|
|
t.Errorf("provisioning notice should be downgraded to info: %s", events[0].Severity)
|
|
}
|
|
if events[1].SensorName != "dhcp6c[957]" {
|
|
t.Errorf("proc = %q", events[1].SensorName)
|
|
}
|
|
if events[2].Severity != models.SeverityWarning {
|
|
t.Errorf("pri 3 (err) -> %s, want warning", events[2].Severity)
|
|
}
|
|
}
|
|
|
|
func TestDedupeEvents(t *testing.T) {
|
|
e := models.Event{Source: "BMC/SEL", Description: "x"}
|
|
out := dedupeEvents([]models.Event{e, e, {Source: "BMC/IDL", Description: "x"}})
|
|
if len(out) != 2 {
|
|
t.Fatalf("dedupe kept %d", len(out))
|
|
}
|
|
}
|