package collector import ( "testing" ) func TestParseCPUs_dual_socket(t *testing.T) { out := mustReadFile(t, "testdata/dmidecode_type4.txt") cpus := parseCPUs(out, "CAR315KA0803B90") if len(cpus) != 2 { t.Fatalf("expected 2 CPUs, got %d", len(cpus)) } cpu0 := cpus[0] if cpu0.Socket == nil || *cpu0.Socket != 0 { t.Errorf("cpu0 socket: got %v, want 0", cpu0.Socket) } if cpu0.Model == nil || *cpu0.Model != "Intel(R) Xeon(R) Gold 6530" { t.Errorf("cpu0 model: got %v", cpu0.Model) } if cpu0.Manufacturer == nil || *cpu0.Manufacturer != "Intel" { t.Errorf("cpu0 manufacturer: got %v, want Intel", cpu0.Manufacturer) } if cpu0.Cores == nil || *cpu0.Cores != 32 { t.Errorf("cpu0 cores: got %v, want 32", cpu0.Cores) } if cpu0.Threads == nil || *cpu0.Threads != 64 { t.Errorf("cpu0 threads: got %v, want 64", cpu0.Threads) } if cpu0.MaxFrequencyMHz == nil || *cpu0.MaxFrequencyMHz != 4000 { t.Errorf("cpu0 max_frequency_mhz: got %v, want 4000", cpu0.MaxFrequencyMHz) } if cpu0.FrequencyMHz == nil || *cpu0.FrequencyMHz != 2100 { t.Errorf("cpu0 frequency_mhz: got %v, want 2100", cpu0.FrequencyMHz) } if cpu0.Status == nil || *cpu0.Status != "OK" { t.Errorf("cpu0 status: got %v, want OK", cpu0.Status) } // Intel Xeon serial not available → fallback if cpu0.SerialNumber == nil || *cpu0.SerialNumber != "CAR315KA0803B90-CPU-0" { t.Errorf("cpu0 serial fallback: got %v, want CAR315KA0803B90-CPU-0", cpu0.SerialNumber) } cpu1 := cpus[1] if cpu1.Socket == nil || *cpu1.Socket != 1 { t.Errorf("cpu1 socket: got %v, want 1", cpu1.Socket) } if cpu1.SerialNumber == nil || *cpu1.SerialNumber != "CAR315KA0803B90-CPU-1" { t.Errorf("cpu1 serial fallback: got %v, want CAR315KA0803B90-CPU-1", cpu1.SerialNumber) } } func TestParseCPUs_unpopulated_skipped(t *testing.T) { out := mustReadFile(t, "testdata/dmidecode_type4_disabled.txt") cpus := parseCPUs(out, "BOARD-001") if len(cpus) != 1 { t.Fatalf("expected 1 CPU (unpopulated skipped), got %d", len(cpus)) } if cpus[0].Socket == nil || *cpus[0].Socket != 0 { t.Errorf("expected socket 0, got %v", cpus[0].Socket) } } func TestParseCPUStatus(t *testing.T) { tests := []struct { input string want string }{ {"Populated, Enabled", "OK"}, {"Populated, Disabled By User", statusWarning}, {"Populated, Disabled By BIOS", statusWarning}, {"Unpopulated", statusEmpty}, {"Not Populated", statusEmpty}, {"Unknown", statusUnknown}, {"", statusUnknown}, } for _, tt := range tests { got := parseCPUStatus(tt.input) if got != tt.want { t.Errorf("parseCPUStatus(%q) = %q, want %q", tt.input, got, tt.want) } } } func TestParseSocketIndex(t *testing.T) { tests := []struct { input string want int ok bool }{ {"CPU0", 0, true}, {"CPU1", 1, true}, {"Processor 1", 1, true}, {"Socket 2", 2, true}, {"", 0, false}, {"No digits here", 0, false}, } for _, tt := range tests { got, ok := parseSocketIndex(tt.input) if ok != tt.ok || got != tt.want { t.Errorf("parseSocketIndex(%q) = (%d, %v), want (%d, %v)", tt.input, got, ok, tt.want, tt.ok) } } } func TestCleanManufacturer(t *testing.T) { tests := []struct { input string want string }{ {"Intel(R) Corporation", "Intel"}, {"AMD", "AMD"}, {"To Be Filled By O.E.M.", ""}, {" Intel(R) Corporation ", "Intel"}, } for _, tt := range tests { got := cleanManufacturer(tt.input) if got != tt.want { t.Errorf("cleanManufacturer(%q) = %q, want %q", tt.input, got, tt.want) } } } func TestParseMHz(t *testing.T) { tests := []struct { input string want int }{ {"4000 MHz", 4000}, {"2100 MHz", 2100}, {"Unknown", 0}, {"", 0}, {"N/A", 0}, } for _, tt := range tests { got := parseMHz(tt.input) if got != tt.want { t.Errorf("parseMHz(%q) = %d, want %d", tt.input, got, tt.want) } } }