feat(models): resolve CPU serial from source PPIN as common fallback

Centralize CPU identity in models.ResolveCPUSerialNumber: an explicit
source serial wins, otherwise a valid source PPIN is used, placeholders
rejected. Dell, H3C and Redfish apply it while parsing; canonical-device
and Reanimator conversion apply it again at the output boundary. No
identity is synthesized from socket/model/board serial.

See ADL-058.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-08-27 17:05:40 +03:00
co-authored by Claude Sonnet 5
parent 9d701885da
commit 07c270cda2
13 changed files with 122 additions and 19 deletions
+25
View File
@@ -0,0 +1,25 @@
package models
import "testing"
func TestResolveCPUSerialNumber(t *testing.T) {
tests := []struct {
name string
serial string
ppin string
want string
}{
{name: "serial has priority", serial: "CPU-SERIAL", ppin: "D46E5D6B1D3E40E1", want: "CPU-SERIAL"},
{name: "PPIN fallback", ppin: " D46E5D6B1D3E40E1 ", want: "D46E5D6B1D3E40E1"},
{name: "placeholder serial falls back", serial: "Unknown", ppin: "D44F8D6B9155EE0E", want: "D44F8D6B9155EE0E"},
{name: "placeholder PPIN rejected", ppin: "N/A", want: ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ResolveCPUSerialNumber(tt.serial, tt.ppin); got != tt.want {
t.Fatalf("ResolveCPUSerialNumber(%q, %q) = %q, want %q", tt.serial, tt.ppin, got, tt.want)
}
})
}
}