package easy_bee import ( "testing" "time" "git.mchus.pro/mchus/logpile/internal/parser" ) func TestDetectBeeSupportArchive(t *testing.T) { p := &Parser{} files := []parser.ExtractedFile{ { Path: "bee-support-debian-20260325-162030/manifest.txt", Content: []byte("bee_version=1.0.0\nhost=debian\ngenerated_at_utc=2026-03-25T16:20:30Z\nexport_dir=/appdata/bee/export\n"), }, { Path: "bee-support-debian-20260325-162030/export/bee-audit.json", Content: []byte(`{"hardware":{"board":{"serial_number":"SN-BEE-001"}}}`), }, { Path: "bee-support-debian-20260325-162030/export/runtime-health.json", Content: []byte(`{"status":"PARTIAL"}`), }, } if got := p.Detect(files); got < 90 { t.Fatalf("expected high confidence detect score, got %d", got) } } func TestDetectRejectsNonBeeArchive(t *testing.T) { p := &Parser{} files := []parser.ExtractedFile{ { Path: "random/manifest.txt", Content: []byte("host=test\n"), }, { Path: "random/export/runtime-health.json", Content: []byte(`{"status":"OK"}`), }, } if got := p.Detect(files); got != 0 { t.Fatalf("expected detect score 0, got %d", got) } } func TestParseBeeAuditSnapshot(t *testing.T) { p := &Parser{} files := []parser.ExtractedFile{ { Path: "bee-support-debian-20260325-162030/manifest.txt", Content: []byte("bee_version=1.0.0\nhost=debian\ngenerated_at_utc=2026-03-25T16:20:30Z\nexport_dir=/appdata/bee/export\n"), }, { Path: "bee-support-debian-20260325-162030/export/bee-audit.json", Content: []byte(`{ "source_type": "manual", "target_host": "debian", "collected_at": "2026-03-25T16:08:09Z", "runtime": { "status": "PARTIAL", "checked_at": "2026-03-25T16:07:56Z", "network_status": "OK", "issues": [ { "code": "nvidia_kernel_module_missing", "severity": "warning", "description": "NVIDIA kernel module is not loaded." } ], "services": [ { "name": "bee-web", "status": "inactive" } ] }, "hardware": { "board": { "manufacturer": "Supermicro", "product_name": "AS-4124GQ-TNMI", "serial_number": "S490387X4418273", "part_number": "H12DGQ-NT6", "uuid": "d868ae00-a61f-11ee-8000-7cc255e10309" }, "firmware": [ { "device_name": "BIOS", "version": "2.8" } ], "cpus": [ { "status": "OK", "status_checked_at": "2026-03-25T16:08:09Z", "socket": 1, "model": "AMD EPYC 7763 64-Core Processor", "cores": 64, "threads": 128, "frequency_mhz": 2450, "max_frequency_mhz": 3525 } ], "memory": [ { "status": "OK", "status_checked_at": "2026-03-25T16:08:09Z", "slot": "P1-DIMMA1", "location": "P0_Node0_Channel0_Dimm0", "present": true, "size_mb": 32768, "type": "DDR4", "max_speed_mhz": 3200, "current_speed_mhz": 2933, "manufacturer": "SK Hynix", "serial_number": "80AD01224887286666", "part_number": "HMA84GR7DJR4N-XN" } ], "storage": [ { "status": "Unknown", "status_checked_at": "2026-03-25T16:08:09Z", "slot": "nvme0n1", "type": "NVMe", "model": "KCD6XLUL960G", "serial_number": "2470A00XT5M8", "interface": "NVMe", "present": true } ], "pcie_devices": [ { "status": "OK", "status_checked_at": "2026-03-25T16:08:09Z", "slot": "0000:05:00.0", "vendor_id": 5555, "device_id": 4123, "device_class": "EthernetController", "manufacturer": "Mellanox Technologies", "model": "MT28908 Family [ConnectX-6]", "link_width": 16, "link_speed": "Gen4", "max_link_width": 16, "max_link_speed": "Gen4", "mac_addresses": ["94:6d:ae:9a:75:4a"], "present": true } ], "sensors": { "power": [ { "name": "PPT", "location": "amdgpu-pci-1100", "power_w": 95 } ], "temperatures": [ { "name": "Composite", "location": "nvme-pci-0600", "celsius": 28.85, "threshold_warning_celsius": 72.85, "threshold_critical_celsius": 81.85, "status": "OK" } ] } } }`), }, } result, err := p.Parse(files) if err != nil { t.Fatalf("parse failed: %v", err) } if result.Hardware == nil { t.Fatal("expected hardware to be populated") } if result.TargetHost != "debian" { t.Fatalf("expected target host debian, got %q", result.TargetHost) } wantCollectedAt := time.Date(2026, 3, 25, 16, 8, 9, 0, time.UTC) if !result.CollectedAt.Equal(wantCollectedAt) { t.Fatalf("expected collected_at %s, got %s", wantCollectedAt, result.CollectedAt) } if result.Hardware.BoardInfo.SerialNumber != "S490387X4418273" { t.Fatalf("unexpected board serial %q", result.Hardware.BoardInfo.SerialNumber) } if len(result.Hardware.CPUs) != 1 { t.Fatalf("expected 1 cpu, got %d", len(result.Hardware.CPUs)) } if len(result.Hardware.Memory) != 1 { t.Fatalf("expected 1 dimm, got %d", len(result.Hardware.Memory)) } if len(result.Hardware.Storage) != 1 { t.Fatalf("expected 1 storage device, got %d", len(result.Hardware.Storage)) } if len(result.Hardware.PCIeDevices) != 1 { t.Fatalf("expected 1 pcie device, got %d", len(result.Hardware.PCIeDevices)) } if result.Hardware.PCIeDevices[0].BDF != "0000:05:00.0" { t.Fatalf("expected BDF to be normalized from slot, got %q", result.Hardware.PCIeDevices[0].BDF) } if len(result.Sensors) != 2 { t.Fatalf("expected 2 flattened sensors, got %d", len(result.Sensors)) } if len(result.Events) < 3 { t.Fatalf("expected runtime events to be created, got %d", len(result.Events)) } if len(result.FRU) == 0 { t.Fatal("expected board FRU fallback to be populated") } }