Merge branch 'test/full-coverage'
This commit is contained in:
@@ -128,3 +128,28 @@ func TestRunAuditWritesFailureReportAndSummary(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCollectAuditJobsAndReanimatorNoCPU(t *testing.T) {
|
||||||
|
input := t.TempDir()
|
||||||
|
output := filepath.Join(input, "output")
|
||||||
|
plain := filepath.Join(input, "nvidia-bug-report.log")
|
||||||
|
if err := os.WriteFile(plain, []byte("NVIDIA bug report log file\nnvidia-bug-report.sh\n"), 0o644); err != nil {
|
||||||
|
t.Fatalf("write fixture: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
jobs, err := collectAuditJobs(input, output, true, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("collectAuditJobs: %v", err)
|
||||||
|
}
|
||||||
|
if len(jobs) != 1 || jobs[0].relative != "nvidia-bug-report.log" {
|
||||||
|
t.Fatalf("unexpected jobs: %+v", jobs)
|
||||||
|
}
|
||||||
|
|
||||||
|
summary, err := runReanimatorExport(input, output, "v1", 1, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("runReanimatorExport: %v", err)
|
||||||
|
}
|
||||||
|
if summary.FilesFound != 1 || summary.FilesParsed != 1 || summary.FilesNoCPU != 1 || summary.FilesWithCPU != 0 {
|
||||||
|
t.Fatalf("unexpected summary: %+v", summary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -186,6 +186,9 @@ func loadRawExportTreeFromExampleZip(t *testing.T, name string) map[string]inter
|
|||||||
path := filepath.Join("..", "..", "..", "example", name)
|
path := filepath.Join("..", "..", "..", "example", name)
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
t.Skipf("optional example zip %s is not present", path)
|
||||||
|
}
|
||||||
t.Fatalf("open example zip %s: %v", path, err)
|
t.Fatalf("open example zip %s: %v", path, err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|||||||
@@ -28,6 +28,26 @@ func TestExtractArchiveFromReaderTXT(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArchiveFileSelectionHelpers(t *testing.T) {
|
||||||
|
extensions := SupportedArchiveExtensions()
|
||||||
|
if len(extensions) == 0 || extensions[0] != ".ahs" {
|
||||||
|
t.Fatalf("unexpected supported extensions: %v", extensions)
|
||||||
|
}
|
||||||
|
if !IsSupportedArchiveFilename("report.TGZ") || IsSupportedArchiveFilename("report.bin") {
|
||||||
|
t.Fatal("unexpected supported archive detection")
|
||||||
|
}
|
||||||
|
files := []ExtractedFile{{Path: "logs/System.LOG"}, {Path: "config.json"}, {Path: "nested/event.log"}}
|
||||||
|
if got := FindFileByPattern(files, "log"); len(got) != 2 {
|
||||||
|
t.Fatalf("FindFileByPattern = %+v", got)
|
||||||
|
}
|
||||||
|
if got := FindFileByName(files, "EVENT.LOG"); got == nil || got.Path != "nested/event.log" {
|
||||||
|
t.Fatalf("FindFileByName = %+v", got)
|
||||||
|
}
|
||||||
|
if got := FindFileByName(files, "missing"); got != nil {
|
||||||
|
t.Fatalf("expected missing file, got %+v", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestExtractArchiveTXT(t *testing.T) {
|
func TestExtractArchiveTXT(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
path := filepath.Join(dir, "sample.txt")
|
path := filepath.Join(dir, "sample.txt")
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
package nvidia_bug_report
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.mchus.pro/mchus/logpile/internal/models"
|
||||||
|
"git.mchus.pro/mchus/logpile/internal/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParserParseInventorySections(t *testing.T) {
|
||||||
|
content := `NVIDIA bug report log file
|
||||||
|
nvidia-bug-report.sh Version: 1
|
||||||
|
Date: Fri Dec 12 10:14:49 EST 2025
|
||||||
|
System Information
|
||||||
|
Manufacturer: Acme
|
||||||
|
Product Name: GPU Server
|
||||||
|
Version: rev-1
|
||||||
|
Serial Number: SYS-1
|
||||||
|
UUID: uuid-1
|
||||||
|
|
||||||
|
Processor Information
|
||||||
|
Version: NVIDIA Grace CPU
|
||||||
|
Serial Number: CPU-1
|
||||||
|
Core Count: 72
|
||||||
|
Thread Count: 144
|
||||||
|
Max Speed: 3.2 GHz
|
||||||
|
Current Speed: 2800 MHz
|
||||||
|
Status: Populated, Enabled
|
||||||
|
|
||||||
|
Memory Device
|
||||||
|
Size: 64 GB
|
||||||
|
Locator: DIMM_A1
|
||||||
|
Bank Locator: BANK 0
|
||||||
|
Type: DDR5
|
||||||
|
Type Detail: Synchronous
|
||||||
|
Speed: 5600 MT/s
|
||||||
|
Configured Memory Speed: 5200 MT/s
|
||||||
|
Manufacturer: Micron
|
||||||
|
Serial Number: MEM-1
|
||||||
|
Part Number: PN-1
|
||||||
|
Rank: 2
|
||||||
|
|
||||||
|
System Power Supply
|
||||||
|
Location: PSU1
|
||||||
|
Name: Power Supply
|
||||||
|
Manufacturer: Delta
|
||||||
|
Serial Number: PSU-SN
|
||||||
|
Model Part Number: DPS-3000
|
||||||
|
Revision: 1.0
|
||||||
|
Max Power Capacity: 3000 W
|
||||||
|
Status: Present, OK
|
||||||
|
|
||||||
|
/proc/driver/nvidia/gpus/0000:1a:00.0/information
|
||||||
|
Model: NVIDIA B200
|
||||||
|
IRQ: 42
|
||||||
|
GPU UUID: GPU-1
|
||||||
|
Video BIOS: 96.00
|
||||||
|
Bus Type: PCIe
|
||||||
|
DMA Size: 47 bits
|
||||||
|
DMA Mask: 0xffff
|
||||||
|
Bus Location: 0000:1a:00.0
|
||||||
|
Device Minor: 0
|
||||||
|
GPU Excluded: No
|
||||||
|
___
|
||||||
|
GPU 00000000:1A:00.0
|
||||||
|
Serial Number : GPU-SN
|
||||||
|
0000:5e:00.0 Ethernet controller [0200]: Mellanox Technologies ConnectX-7 [15b3:101e]
|
||||||
|
Physical Slot: SLOT-1
|
||||||
|
Vital Product Data
|
||||||
|
Product Name: Dual-port QSFP56 Adapter
|
||||||
|
[PN] Part number: MCX75310AAS
|
||||||
|
[SN] Serial number: NIC-1
|
||||||
|
[EC] Engineering changes: A1
|
||||||
|
End
|
||||||
|
NVRM version: 570.172.08
|
||||||
|
`
|
||||||
|
|
||||||
|
p := &Parser{}
|
||||||
|
result, err := p.Parse([]parser.ExtractedFile{{Path: "nvidia-bug-report.log", Content: []byte(content)}})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Parse: %v", err)
|
||||||
|
}
|
||||||
|
if result.Hardware.BoardInfo.ProductName != "GPU Server" || result.Hardware.BoardInfo.SerialNumber != "SYS-1" {
|
||||||
|
t.Fatalf("unexpected board: %+v", result.Hardware.BoardInfo)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.CPUs) != 1 || result.Hardware.CPUs[0].Cores != 72 || result.Hardware.CPUs[0].MaxFreqMHz != 3200 {
|
||||||
|
t.Fatalf("unexpected CPUs: %+v", result.Hardware.CPUs)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.Memory) != 1 || result.Hardware.Memory[0].SizeMB != 65536 || result.Hardware.Memory[0].Ranks != 2 {
|
||||||
|
t.Fatalf("unexpected memory: %+v", result.Hardware.Memory)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.PowerSupply) != 1 || !result.Hardware.PowerSupply[0].Present || result.Hardware.PowerSupply[0].WattageW != 3000 {
|
||||||
|
t.Fatalf("unexpected power supplies: %+v", result.Hardware.PowerSupply)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.GPUs) != 1 || result.Hardware.GPUs[0].SerialNumber != "GPU-SN" || result.Hardware.GPUs[0].IRQ != 42 {
|
||||||
|
t.Fatalf("unexpected GPUs: %+v", result.Hardware.GPUs)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.NetworkAdapters) != 1 {
|
||||||
|
t.Fatalf("unexpected network adapters: %+v", result.Hardware.NetworkAdapters)
|
||||||
|
}
|
||||||
|
nic := result.Hardware.NetworkAdapters[0]
|
||||||
|
if nic.Model != "Dual-port QSFP56 Adapter" || nic.PortCount != 2 || nic.PortType != "QSFP56" || nic.SerialNumber != "NIC-1" {
|
||||||
|
t.Fatalf("unexpected network adapter: %+v", nic)
|
||||||
|
}
|
||||||
|
if !hasEvent(result.Events, "Memory Configuration") || !hasEvent(result.Events, "GPU Detection") || !hasEvent(result.Events, "Driver Version") {
|
||||||
|
t.Fatalf("expected inventory events, got %+v", result.Events)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParserDetectAndScalarParsers(t *testing.T) {
|
||||||
|
p := &Parser{}
|
||||||
|
if got := p.Detect([]parser.ExtractedFile{{Path: "nvidia-bug-report.log", Content: []byte("nvidia-bug-report.sh NVIDIA bug report log file")}}); got != 85 {
|
||||||
|
t.Fatalf("Detect = %d", got)
|
||||||
|
}
|
||||||
|
if got := p.Detect(nil); got != 0 {
|
||||||
|
t.Fatalf("empty Detect = %d", got)
|
||||||
|
}
|
||||||
|
if p.Name() == "" || p.Version() == "" {
|
||||||
|
t.Fatal("expected parser identity")
|
||||||
|
}
|
||||||
|
for _, tc := range []struct {
|
||||||
|
value string
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
{"2.5 GHz", 2500}, {"3200 MHz", 3200}, {"bad", 0},
|
||||||
|
} {
|
||||||
|
if got := parseCPUSpeed(tc.value); got != tc.want {
|
||||||
|
t.Errorf("parseCPUSpeed(%q) = %d, want %d", tc.value, got, tc.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if got := parseMemorySize("2 TB"); got != 2*1024*1024 {
|
||||||
|
t.Fatalf("parseMemorySize = %d", got)
|
||||||
|
}
|
||||||
|
if got := parseMemorySpeed("5600 MT/s"); got != 5600 {
|
||||||
|
t.Fatalf("parseMemorySpeed = %d", got)
|
||||||
|
}
|
||||||
|
if got := parsePowerWattage("1200 Watts"); got != 1200 {
|
||||||
|
t.Fatalf("parsePowerWattage = %d", got)
|
||||||
|
}
|
||||||
|
if got := formatGPUSummary([]models.GPU{{BDF: "0000:1a:00.0", Model: "B200"}}); !strings.Contains(got, "B200") {
|
||||||
|
t.Fatalf("formatGPUSummary = %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasEvent(events []models.Event, eventType string) bool {
|
||||||
|
for _, event := range events {
|
||||||
|
if event.EventType == eventType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package unraid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.mchus.pro/mchus/logpile/internal/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseInventoryAndLogs(t *testing.T) {
|
||||||
|
files := []parser.ExtractedFile{
|
||||||
|
{Path: "diagnostics/system/motherboard.txt", Content: []byte(`Acme NAS Board
|
||||||
|
BIOS Information
|
||||||
|
Vendor: Acme
|
||||||
|
Version: 1.2.3
|
||||||
|
`)},
|
||||||
|
{Path: "diagnostics/system/meminfo.txt", Content: []byte(`Handle 0x0010, DMI type 17, 84 bytes
|
||||||
|
Memory Device
|
||||||
|
Size: 32 GB
|
||||||
|
Locator: DIMM_A1
|
||||||
|
Bank Locator: BANK 0
|
||||||
|
Type: DDR5
|
||||||
|
Speed: 5600 MT/s
|
||||||
|
Configured Memory Speed: 5200 MT/s
|
||||||
|
Manufacturer: Micron
|
||||||
|
Serial Number: MEM-1
|
||||||
|
Part Number: PN-1
|
||||||
|
Rank: 2
|
||||||
|
`)},
|
||||||
|
{Path: "diagnostics/system/ifconfig.txt", Content: []byte("eth0 UP 192.0.2.10/24\nlo UP 127.0.0.1\n")},
|
||||||
|
{Path: "diagnostics/system/ethtool.txt", Content: []byte(`Settings for eth0:
|
||||||
|
driver: mlx5_core
|
||||||
|
firmware-version: 1.0
|
||||||
|
bus-info: 0000:5e:00.0
|
||||||
|
Speed: 100000Mb/s
|
||||||
|
Link detected: yes
|
||||||
|
`)},
|
||||||
|
{Path: "diagnostics/system/lspci.txt", Content: []byte(`5e:00.0 Ethernet controller [0200]: Mellanox Technologies Network Adapter [15b3:101e]
|
||||||
|
3b:00.0 Non-Volatile memory controller [0108]: Acme NVMe [1234:5678]
|
||||||
|
`)},
|
||||||
|
{Path: "diagnostics/system/vars.txt", Content: []byte(`disks
|
||||||
|
(
|
||||||
|
[disk1] => Array
|
||||||
|
(
|
||||||
|
[device] => sda
|
||||||
|
[id] => WDC-1
|
||||||
|
[size] => 2097152
|
||||||
|
[temp] => 55
|
||||||
|
[fsType] => xfs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flashGUID
|
||||||
|
(
|
||||||
|
[flashGUID] => HOST-1
|
||||||
|
)
|
||||||
|
`)},
|
||||||
|
{Path: "diagnostics/logs/syslog.txt", Content: []byte("Feb 5 23:33:01 host kernel: fatal disk error\nFeb 5 23:33:02 host daemon: normal message\n")},
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := (&Parser{}).Parse(files)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Parse: %v", err)
|
||||||
|
}
|
||||||
|
if result.Hardware.BoardInfo.Manufacturer != "Acme" || result.Hardware.BoardInfo.ProductName != "Acme NAS Board" {
|
||||||
|
t.Fatalf("unexpected board: %+v", result.Hardware.BoardInfo)
|
||||||
|
}
|
||||||
|
if result.Hardware.BoardInfo.SerialNumber != "HOST-1" {
|
||||||
|
t.Fatalf("host serial = %q", result.Hardware.BoardInfo.SerialNumber)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.Memory) != 1 || result.Hardware.Memory[0].Slot != "DIMM_A1" || result.Hardware.Memory[0].SizeMB != 32768 {
|
||||||
|
t.Fatalf("unexpected memory: %+v", result.Hardware.Memory)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.NetworkAdapters) != 1 || result.Hardware.NetworkAdapters[0].Slot != "eth0" || result.Hardware.NetworkAdapters[0].Status != "ok" {
|
||||||
|
t.Fatalf("unexpected NICs: %+v", result.Hardware.NetworkAdapters)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.PCIeDevices) != 2 {
|
||||||
|
t.Fatalf("unexpected PCIe devices: %+v", result.Hardware.PCIeDevices)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.Storage) != 1 || result.Hardware.Storage[0].Slot != "disk1" || result.Hardware.Storage[0].SizeGB != 2 {
|
||||||
|
t.Fatalf("unexpected storage: %+v", result.Hardware.Storage)
|
||||||
|
}
|
||||||
|
if len(result.Sensors) != 1 || result.Sensors[0].Status != "warning" {
|
||||||
|
t.Fatalf("unexpected sensors: %+v", result.Sensors)
|
||||||
|
}
|
||||||
|
if len(result.Events) != 2 || result.Events[0].Severity != "critical" {
|
||||||
|
t.Fatalf("unexpected syslog events: %+v", result.Events)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnraidParsingHelpers(t *testing.T) {
|
||||||
|
if got := firstWords("Mellanox Technologies Adapter", 2); got != "Mellanox Technologies" {
|
||||||
|
t.Fatalf("firstWords = %q", got)
|
||||||
|
}
|
||||||
|
if got := getTempStatus(60); got != "critical" {
|
||||||
|
t.Fatalf("temperature status = %q", got)
|
||||||
|
}
|
||||||
|
if got := getTempStatus(20); got != "ok" {
|
||||||
|
t.Fatalf("temperature status = %q", got)
|
||||||
|
}
|
||||||
|
if got := extractDiskSection(" [disk1] => Array\n (\n [id] => disk\n )", "disk1"); got == "" {
|
||||||
|
t.Fatal("expected disk section")
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -238,7 +238,7 @@ func parseStorageAndSMART(content string, result *models.AnalysisResult) {
|
|||||||
storageBySlot := make(map[string]*models.Storage)
|
storageBySlot := make(map[string]*models.Storage)
|
||||||
scsiRe := regexp.MustCompile(`(?m)^<([^>]+)>\s+at\s+scbus\d+\s+target\s+\d+\s+lun\s+\d+\s+\(([^,]+),([^)]+)\)$`)
|
scsiRe := regexp.MustCompile(`(?m)^<([^>]+)>\s+at\s+scbus\d+\s+target\s+\d+\s+lun\s+\d+\s+\(([^,]+),([^)]+)\)$`)
|
||||||
for _, m := range scsiRe.FindAllStringSubmatch(content, -1) {
|
for _, m := range scsiRe.FindAllStringSubmatch(content, -1) {
|
||||||
slot := strings.TrimSpace(m[3])
|
slot := strings.TrimSpace(m[2])
|
||||||
model, fw := splitModelAndFirmware(strings.TrimSpace(m[1]))
|
model, fw := splitModelAndFirmware(strings.TrimSpace(m[1]))
|
||||||
entry := &models.Storage{
|
entry := &models.Storage{
|
||||||
Slot: slot,
|
Slot: slot,
|
||||||
|
|||||||
+82
@@ -38,6 +38,88 @@ loader_brand="XigmaNAS"`),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParserParseInlineDump(t *testing.T) {
|
||||||
|
p := &Parser{}
|
||||||
|
result, err := p.Parse([]parser.ExtractedFile{{Path: "diagnostic.txt", Content: []byte(`Version:
|
||||||
|
--------
|
||||||
|
14.3.0.5
|
||||||
|
smbios.bios.version="F.22"
|
||||||
|
smbios.system.maker="Acme"
|
||||||
|
smbios.system.product="NAS-1"
|
||||||
|
smbios.system.serial="SN-1"
|
||||||
|
smbios.system.uuid="uuid-1"
|
||||||
|
FreeBSD/SMP: 1 package(s) x 4 core(s)
|
||||||
|
CPU: AMD Ryzen 5 3600 (3600.00-MHz)
|
||||||
|
CPU: AMD Ryzen 5 3600 (3600.00-MHz)
|
||||||
|
real memory = 8589934592 (8192 MB)
|
||||||
|
10:10AM up 2 days, 3 users, load averages: 0.10, 0.20, 0.30
|
||||||
|
state: DEGRADED
|
||||||
|
<WDC WD10EZEX 1.01> at scbus0 target 0 lun 0 (da0,pass0)
|
||||||
|
S.M.A.R.T. [/dev/da0]:
|
||||||
|
--------
|
||||||
|
Device Model: WDC WD10EZEX
|
||||||
|
Serial Number: DISK-1
|
||||||
|
Firmware Version: 1.01
|
||||||
|
User Capacity: 1,000,000,000 bytes
|
||||||
|
SMART overall-health self-assessment test result: FAILED
|
||||||
|
194 Temperature_Celsius 0x0022 100 100 000 Old_age Always - 41
|
||||||
|
Last 275 System log entries:
|
||||||
|
--------
|
||||||
|
2026-01-02T03:04:05+00:00 host kernel: fatal disk error
|
||||||
|
Last 275 SMARTD log entries:
|
||||||
|
--------
|
||||||
|
Jan 2 03:04:05 host smartd: warning temperature
|
||||||
|
Last 275 Daemon log entries:
|
||||||
|
--------
|
||||||
|
plain informational line
|
||||||
|
`)}})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Parse: %v", err)
|
||||||
|
}
|
||||||
|
if result.Hardware.BoardInfo.ProductName != "NAS-1" || len(result.Hardware.Firmware) != 2 {
|
||||||
|
t.Fatalf("unexpected board or firmware: %+v / %+v", result.Hardware.BoardInfo, result.Hardware.Firmware)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.CPUs) != 1 || result.Hardware.CPUs[0].Cores != 4 {
|
||||||
|
t.Fatalf("unexpected CPUs: %+v", result.Hardware.CPUs)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.Memory) != 1 || result.Hardware.Memory[0].SizeMB != 8192 {
|
||||||
|
t.Fatalf("unexpected memory: %+v", result.Hardware.Memory)
|
||||||
|
}
|
||||||
|
if len(result.Hardware.Storage) != 1 || result.Hardware.Storage[0].SizeGB != 1 || result.Hardware.Storage[0].SerialNumber != "DISK-1" {
|
||||||
|
t.Fatalf("unexpected storage: %+v", result.Hardware.Storage)
|
||||||
|
}
|
||||||
|
if len(result.Sensors) != 1 || result.Sensors[0].Status != "warning" {
|
||||||
|
t.Fatalf("unexpected sensors: %+v", result.Sensors)
|
||||||
|
}
|
||||||
|
if len(result.Events) != 6 {
|
||||||
|
t.Fatalf("expected uptime, ZFS, SMART, and three log events, got %+v", result.Events)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXigmaNASHelpers(t *testing.T) {
|
||||||
|
if model, fw := splitModelAndFirmware("disk model 1.00"); model != "disk model" || fw != "1.00" {
|
||||||
|
t.Fatalf("splitModelAndFirmware = %q, %q", model, fw)
|
||||||
|
}
|
||||||
|
if got := guessStorageType("cd0"); got != "optical" {
|
||||||
|
t.Fatalf("optical type = %q", got)
|
||||||
|
}
|
||||||
|
if got := guessStorageType("ada0"); got != "hdd" {
|
||||||
|
t.Fatalf("HDD type = %q", got)
|
||||||
|
}
|
||||||
|
if got := parseCapacityBytes("invalid"); got != 0 {
|
||||||
|
t.Fatalf("invalid capacity = %d", got)
|
||||||
|
}
|
||||||
|
if got := classifyEventSeverity("all good"); got != "info" {
|
||||||
|
t.Fatalf("info severity = %q", got)
|
||||||
|
}
|
||||||
|
if got := classifyEventSeverity("kernel panic"); got != "critical" {
|
||||||
|
t.Fatalf("critical severity = %q", got)
|
||||||
|
}
|
||||||
|
if got := extractSyslogMessage("a: message"); got != "message" {
|
||||||
|
t.Fatalf("syslog message = %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParserParseExample(t *testing.T) {
|
func TestParserParseExample(t *testing.T) {
|
||||||
p := &Parser{}
|
p := &Parser{}
|
||||||
|
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ func TestHandleChartCurrent_RendersCurrentReanimatorSnapshot(t *testing.T) {
|
|||||||
if !strings.Contains(body, "SYS-TEST - SN123") {
|
if !strings.Contains(body, "SYS-TEST - SN123") {
|
||||||
t.Fatalf("expected chart title in body, got %q", body)
|
t.Fatalf("expected chart title in body, got %q", body)
|
||||||
}
|
}
|
||||||
if !strings.Contains(body, `/chart/static/view.css`) {
|
if !strings.Contains(body, `static/view.css`) {
|
||||||
t.Fatalf("expected rewritten chart css path, got %q", body)
|
t.Fatalf("expected chart css path, got %q", body)
|
||||||
}
|
}
|
||||||
if !strings.Contains(body, `/chart/static/view.js`) {
|
if !strings.Contains(body, `static/view.js`) {
|
||||||
t.Fatalf("expected rewritten chart js path, got %q", body)
|
t.Fatalf("expected chart js path, got %q", body)
|
||||||
}
|
}
|
||||||
if !strings.Contains(body, "Snapshot Metadata") {
|
if !strings.Contains(body, "Snapshot Metadata") {
|
||||||
t.Fatalf("expected rendered chart output, got %q", body)
|
t.Fatalf("expected rendered chart output, got %q", body)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ import (
|
|||||||
func TestReanimatorExport_RedfishExampleDoesNotDuplicateCPUs(t *testing.T) {
|
func TestReanimatorExport_RedfishExampleDoesNotDuplicateCPUs(t *testing.T) {
|
||||||
payload, err := os.ReadFile(filepath.Join("..", "..", "example", "2026-03-11 (SYS-821GE-TNHR) - A514359X5C08846.zip"))
|
payload, err := os.ReadFile(filepath.Join("..", "..", "example", "2026-03-11 (SYS-821GE-TNHR) - A514359X5C08846.zip"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
t.Skip("optional example bundle is not present")
|
||||||
|
}
|
||||||
t.Fatalf("read example bundle: %v", err)
|
t.Fatalf("read example bundle: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user