Adds board and memory parser test fixtures based on real dmidecode output from Dell PowerEdge R740xd, HPE ProLiant DL380 Gen10, and Supermicro SYS-6028R-WTR sourced from the linuxhw/DMI dataset. Extends cleanDMIValue with four additional vendor placeholder strings found in the dataset: "0123456789", "1234567890", "NOT AVAILABLE", and "TO BE FILLED BY O.E.M" (without trailing dot). Adds memory_test.go covering mixed populated/empty DIMM slots and both GB and MB size formats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
198 lines
6.0 KiB
Go
198 lines
6.0 KiB
Go
package collector
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseBoard(t *testing.T) {
|
|
type1 := mustReadFile(t, "testdata/dmidecode_type1.txt")
|
|
type2 := mustReadFile(t, "testdata/dmidecode_type2.txt")
|
|
|
|
board := parseBoard(type1, type2)
|
|
|
|
if board.SerialNumber != "CAR315KA0803B90" {
|
|
t.Errorf("serial_number: got %q, want %q", board.SerialNumber, "CAR315KA0803B90")
|
|
}
|
|
if board.Manufacturer == nil || *board.Manufacturer != "Inspur" {
|
|
t.Errorf("manufacturer: got %v, want Inspur", board.Manufacturer)
|
|
}
|
|
if board.ProductName == nil || *board.ProductName != "NF5468M7" {
|
|
t.Errorf("product_name: got %v, want NF5468M7", board.ProductName)
|
|
}
|
|
if board.PartNumber == nil || *board.PartNumber != "YZCA-02758-105" {
|
|
t.Errorf("part_number: got %v, want YZCA-02758-105", board.PartNumber)
|
|
}
|
|
if board.UUID == nil || *board.UUID != "a1b2c3d4-e5f6-7890-abcd-ef1234567890" {
|
|
t.Errorf("uuid: got %v, want a1b2c3d4-e5f6-7890-abcd-ef1234567890", board.UUID)
|
|
}
|
|
}
|
|
|
|
func TestParseBoard_emptySerial(t *testing.T) {
|
|
type1 := mustReadFile(t, "testdata/dmidecode_type1_empty_serial.txt")
|
|
|
|
board := parseBoard(type1, "")
|
|
|
|
if board.SerialNumber != "" {
|
|
t.Errorf("expected empty serial for placeholder value, got %q", board.SerialNumber)
|
|
}
|
|
if board.Manufacturer != nil {
|
|
t.Errorf("expected nil manufacturer for placeholder, got %q", *board.Manufacturer)
|
|
}
|
|
if board.UUID != nil {
|
|
t.Errorf("expected nil UUID for 'Not Settable', got %q", *board.UUID)
|
|
}
|
|
}
|
|
|
|
func TestParseBIOSFirmware(t *testing.T) {
|
|
type0 := mustReadFile(t, "testdata/dmidecode_type0.txt")
|
|
fw := parseBIOSFirmware(type0)
|
|
|
|
if len(fw) != 1 {
|
|
t.Fatalf("expected 1 firmware record, got %d", len(fw))
|
|
}
|
|
if fw[0].DeviceName != "BIOS" {
|
|
t.Errorf("device_name: got %q, want BIOS", fw[0].DeviceName)
|
|
}
|
|
if fw[0].Version != "06.08.05" {
|
|
t.Errorf("version: got %q, want 06.08.05", fw[0].Version)
|
|
}
|
|
}
|
|
|
|
func TestParseBIOSFirmware_empty(t *testing.T) {
|
|
fw := parseBIOSFirmware("")
|
|
if len(fw) != 0 {
|
|
t.Errorf("expected no firmware records for empty input, got %d", len(fw))
|
|
}
|
|
}
|
|
|
|
func TestCleanDMIValue(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
want string
|
|
}{
|
|
{"CAR315KA0803B90", "CAR315KA0803B90"},
|
|
{"To Be Filled By O.E.M.", ""},
|
|
{"to be filled by o.e.m.", ""},
|
|
{"Not Specified", ""},
|
|
{"Not Settable", ""},
|
|
{"Unknown", ""},
|
|
{"N/A", ""},
|
|
{"None", ""},
|
|
{"NULL", ""},
|
|
{"Default String", ""},
|
|
{" Inspur ", "Inspur"},
|
|
{"", ""},
|
|
{"0", ""},
|
|
{"0123456789", ""},
|
|
{"1234567890", ""},
|
|
{"Not Available", ""},
|
|
{"To Be Filled By O.E.M", ""},
|
|
}
|
|
for _, tt := range tests {
|
|
got := cleanDMIValue(tt.input)
|
|
if got != tt.want {
|
|
t.Errorf("cleanDMIValue(%q) = %q, want %q", tt.input, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseDMIFields(t *testing.T) {
|
|
type1 := mustReadFile(t, "testdata/dmidecode_type1.txt")
|
|
fields := parseDMIFields(type1, "System Information")
|
|
|
|
if fields["Manufacturer"] != "Inspur" {
|
|
t.Errorf("Manufacturer: got %q", fields["Manufacturer"])
|
|
}
|
|
if fields["Serial Number"] != "CAR315KA0803B90" {
|
|
t.Errorf("Serial Number: got %q", fields["Serial Number"])
|
|
}
|
|
// sub-list items must not be included
|
|
if _, ok := fields["PCI is supported"]; ok {
|
|
t.Error("sub-list item should not appear in fields")
|
|
}
|
|
}
|
|
|
|
func TestParseBoard_Dell(t *testing.T) {
|
|
type1 := mustReadFile(t, "testdata/dmidecode_type1_dell.txt")
|
|
type2 := mustReadFile(t, "testdata/dmidecode_type2_dell.txt")
|
|
|
|
board := parseBoard(type1, type2)
|
|
|
|
if board.SerialNumber != "7SG9F63" {
|
|
t.Errorf("serial_number: got %q, want %q", board.SerialNumber, "7SG9F63")
|
|
}
|
|
if board.Manufacturer == nil || *board.Manufacturer != "Dell Inc." {
|
|
t.Errorf("manufacturer: got %v, want Dell Inc.", board.Manufacturer)
|
|
}
|
|
if board.ProductName == nil || *board.ProductName != "PowerEdge R740xd" {
|
|
t.Errorf("product_name: got %v, want PowerEdge R740xd", board.ProductName)
|
|
}
|
|
// part number comes from type2 Product Name
|
|
if board.PartNumber == nil || *board.PartNumber != "0F9N89" {
|
|
t.Errorf("part_number: got %v, want 0F9N89", board.PartNumber)
|
|
}
|
|
}
|
|
|
|
func TestParseBoard_HPE(t *testing.T) {
|
|
type1 := mustReadFile(t, "testdata/dmidecode_type1_hpe.txt")
|
|
type2 := mustReadFile(t, "testdata/dmidecode_type2_hpe.txt")
|
|
|
|
board := parseBoard(type1, type2)
|
|
|
|
if board.SerialNumber != "CZJ9320CXN" {
|
|
t.Errorf("serial_number: got %q, want %q", board.SerialNumber, "CZJ9320CXN")
|
|
}
|
|
if board.Manufacturer == nil || *board.Manufacturer != "HPE" {
|
|
t.Errorf("manufacturer: got %v, want HPE", board.Manufacturer)
|
|
}
|
|
if board.ProductName == nil || *board.ProductName != "ProLiant DL380 Gen10" {
|
|
t.Errorf("product_name: got %v, want ProLiant DL380 Gen10", board.ProductName)
|
|
}
|
|
if board.PartNumber == nil || *board.PartNumber != "ProLiant DL380 Gen10" {
|
|
t.Errorf("part_number: got %v, want ProLiant DL380 Gen10", board.PartNumber)
|
|
}
|
|
}
|
|
|
|
func TestParseBoard_Supermicro_Placeholders(t *testing.T) {
|
|
type1 := mustReadFile(t, "testdata/dmidecode_type1_supermicro.txt")
|
|
type2 := mustReadFile(t, "testdata/dmidecode_type2_supermicro.txt")
|
|
|
|
board := parseBoard(type1, type2)
|
|
|
|
if board.SerialNumber != "S214726X2A36789" {
|
|
t.Errorf("serial_number: got %q, want %q", board.SerialNumber, "S214726X2A36789")
|
|
}
|
|
if board.Manufacturer == nil || *board.Manufacturer != "Supermicro" {
|
|
t.Errorf("manufacturer: got %v, want Supermicro", board.Manufacturer)
|
|
}
|
|
if board.ProductName == nil || *board.ProductName != "SYS-6028R-WTR" {
|
|
t.Errorf("product_name: got %v, want SYS-6028R-WTR", board.ProductName)
|
|
}
|
|
// "X10DRW-i" is the real part number from type 2
|
|
if board.PartNumber == nil || *board.PartNumber != "X10DRW-i" {
|
|
t.Errorf("part_number: got %v, want X10DRW-i", board.PartNumber)
|
|
}
|
|
}
|
|
|
|
func TestParseBIOSFirmware_Dell(t *testing.T) {
|
|
type0 := mustReadFile(t, "testdata/dmidecode_type0_dell.txt")
|
|
fw := parseBIOSFirmware(type0)
|
|
|
|
if len(fw) != 1 {
|
|
t.Fatalf("expected 1 firmware record, got %d", len(fw))
|
|
}
|
|
if fw[0].Version != "2.5.4" {
|
|
t.Errorf("version: got %q, want 2.5.4", fw[0].Version)
|
|
}
|
|
}
|
|
|
|
func mustReadFile(t *testing.T, path string) string {
|
|
t.Helper()
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("read fixture %s: %v", path, err)
|
|
}
|
|
return string(b)
|
|
}
|