Files
logpile/internal/parser/vendors/inspur/storage_status_test.go
T
Mikhail ChusavitinandClaude Sonnet 5 e7b8a8badc feat(inspur): source-PRI timezone timeline, PPIN serial, NVMe fault storage status
Event ingestion now uses the source syslog PRI and an explicit-offset
timezone timeline instead of assuming host-local time. CPU PPIN is
exported as the source-backed CPU serial, and an active NVMe fault SEL
event promotes the matching drive's storage status.

See ADL-056, ADL-057.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:05:45 +03:00

72 lines
2.5 KiB
Go

package inspur
import (
"fmt"
"testing"
"time"
"git.mchus.pro/mchus/logpile/internal/models"
)
func TestApplyStorageStatusFromEventsMarksOnlyFaultyNVMeCritical(t *testing.T) {
hw := &models.HardwareConfig{}
for i := 1; i <= 7; i++ {
hw.Storage = append(hw.Storage, models.Storage{Slot: fmt.Sprintf("OB%02d", i), Type: "NVMe", Present: true})
}
ts := time.Date(2026, 7, 23, 23, 20, 32, 0, time.UTC)
fault := models.Event{
ID: "0DFF0702",
Timestamp: ts,
Source: "BMC",
EventType: "Assert",
Severity: models.SeverityCritical,
Description: "NVME BP:Front0 NvmeIndex:6 drive fault: Status_Flags error.",
}
applyStorageStatusFromEvents(hw, []models.Event{fault}, []models.Event{fault}, true)
for i := range hw.Storage {
if hw.Storage[i].Slot == "OB07" {
if hw.Storage[i].Status != "Critical" || hw.Storage[i].ErrorDescription == "" {
t.Fatalf("expected OB07 critical with details, got %+v", hw.Storage[i])
}
if len(hw.Storage[i].StatusHistory) != 1 || hw.Storage[i].StatusChangedAt == nil {
t.Fatalf("expected one source-backed status transition, got %+v", hw.Storage[i])
}
continue
}
if hw.Storage[i].Status != "" {
t.Fatalf("unaffected %s must remain unknown/unset, got %q", hw.Storage[i].Slot, hw.Storage[i].Status)
}
}
}
func TestApplyStorageStatusFromEventsDeassertClearsCriticalToUnknown(t *testing.T) {
hw := &models.HardwareConfig{Storage: []models.Storage{{Slot: "OB07", Type: "NVMe", Present: true}}}
asserted := models.Event{
ID: "0DFF0702", Timestamp: time.Date(2026, 7, 23, 23, 20, 32, 0, time.UTC),
EventType: "Assert", Severity: models.SeverityCritical,
Description: "NVME BP:Front0 NvmeIndex:6 drive fault: Status_Flags error.",
}
deasserted := asserted
deasserted.Timestamp = asserted.Timestamp.Add(time.Hour)
deasserted.EventType = "Deassert"
deasserted.Severity = models.SeverityInfo
applyStorageStatusFromEvents(hw, []models.Event{asserted, deasserted}, nil, true)
if hw.Storage[0].Status != "Unknown" || hw.Storage[0].ErrorDescription != "" {
t.Fatalf("expected cleared drive fault to become Unknown, got %+v", hw.Storage[0])
}
if len(hw.Storage[0].StatusHistory) != 2 {
t.Fatalf("expected assert/deassert history, got %+v", hw.Storage[0].StatusHistory)
}
}
func TestStorageFaultIndexIgnoresNVMeInventoryChange(t *testing.T) {
event := models.Event{Description: "PCIE Device #NVME6 Device ID changed; Vendor ID changed"}
if _, ok := storageFaultIndex(event); ok {
t.Fatalf("inventory change must not be treated as an active drive fault")
}
}