package redfishprofile import ( "strings" "testing" ) func TestMatchProfiles_UnknownVendorFallsBackToAggregateProfiles(t *testing.T) { match := MatchProfiles(MatchSignals{ ServiceRootProduct: "Redfish Server", }) if match.Mode != ModeFallback { t.Fatalf("expected fallback mode, got %q", match.Mode) } if len(match.Profiles) < 2 { t.Fatalf("expected aggregated fallback profiles, got %d", len(match.Profiles)) } } func TestMatchProfiles_MSISelectsMatchedMode(t *testing.T) { match := MatchProfiles(MatchSignals{ SystemManufacturer: "Micro-Star International Co., Ltd.", ResourceHints: []string{"/redfish/v1/Chassis/GPU1"}, }) if match.Mode != ModeMatched { t.Fatalf("expected matched mode, got %q", match.Mode) } found := false for _, profile := range match.Profiles { if profile.Name() == "msi" { found = true break } } if !found { t.Fatal("expected msi profile to be selected") } } func TestBuildAcquisitionPlan_FallbackIncludesProfileNotes(t *testing.T) { plan := BuildAcquisitionPlan(MatchSignals{ ServiceRootVendor: "AMI", }) if len(plan.Profiles) == 0 { t.Fatal("expected acquisition plan profiles") } if len(plan.Notes) == 0 { t.Fatal("expected acquisition plan notes") } } func TestBuildAcquisitionPlan_FallbackAddsBroadCrawlTuning(t *testing.T) { plan := BuildAcquisitionPlan(MatchSignals{ ServiceRootProduct: "Unknown Redfish", }) if plan.Mode != ModeFallback { t.Fatalf("expected fallback mode, got %q", plan.Mode) } if plan.Tuning.SnapshotMaxDocuments < 180000 { t.Fatalf("expected widened snapshot cap, got %d", plan.Tuning.SnapshotMaxDocuments) } if plan.Tuning.PrefetchEnabled == nil || !*plan.Tuning.PrefetchEnabled { t.Fatal("expected fallback to force prefetch enabled") } if !plan.Tuning.RecoveryPolicy.EnableCriticalCollectionMemberRetry { t.Fatal("expected fallback to inherit critical member retry recovery") } if !plan.Tuning.RecoveryPolicy.EnableCriticalSlowProbe { t.Fatal("expected fallback to inherit critical slow probe recovery") } } func TestBuildAcquisitionPlan_HGXDisablesNVMePostProbe(t *testing.T) { plan := BuildAcquisitionPlan(MatchSignals{ SystemModel: "HGX B200", ResourceHints: []string{"/redfish/v1/Systems/HGX_Baseboard_0"}, }) if plan.Mode != ModeMatched { t.Fatalf("expected matched mode, got %q", plan.Mode) } if plan.Tuning.NVMePostProbeEnabled == nil || *plan.Tuning.NVMePostProbeEnabled { t.Fatal("expected hgx profile to disable NVMe post-probe") } } func TestResolveAcquisitionPlan_ExpandsScopedPaths(t *testing.T) { signals := MatchSignals{} match := MatchProfiles(signals) plan := BuildAcquisitionPlan(signals) resolved := ResolveAcquisitionPlan(match, plan, DiscoveredResources{ SystemPaths: []string{"/redfish/v1/Systems/1", "/redfish/v1/Systems/2"}, }, signals) joined := joinResolvedPaths(resolved.SeedPaths) for _, wanted := range []string{ "/redfish/v1/Systems/1/SimpleStorage", "/redfish/v1/Systems/1/Storage/IntelVROC", "/redfish/v1/Systems/2/SimpleStorage", "/redfish/v1/Systems/2/Storage/IntelVROC", } { if !containsJoinedPath(joined, wanted) { t.Fatalf("expected resolved seed path %q", wanted) } } } func TestResolveAcquisitionPlan_CriticalBaselineIsShapedByProfiles(t *testing.T) { signals := MatchSignals{} match := MatchProfiles(signals) plan := BuildAcquisitionPlan(signals) resolved := ResolveAcquisitionPlan(match, plan, DiscoveredResources{ SystemPaths: []string{"/redfish/v1/Systems/1"}, ChassisPaths: []string{"/redfish/v1/Chassis/1"}, ManagerPaths: []string{"/redfish/v1/Managers/1"}, }, signals) joined := joinResolvedPaths(resolved.CriticalPaths) for _, wanted := range []string{ "/redfish/v1", "/redfish/v1/Systems/1", "/redfish/v1/Systems/1/Memory", "/redfish/v1/Chassis/1/Assembly", "/redfish/v1/Managers/1/NetworkProtocol", "/redfish/v1/UpdateService", } { if !containsJoinedPath(joined, wanted) { t.Fatalf("expected resolved critical path %q", wanted) } } } func TestResolveAcquisitionPlan_FallbackAppendsPlanBToSeeds(t *testing.T) { signals := MatchSignals{ServiceRootProduct: "Unknown Redfish"} match := MatchProfiles(signals) plan := BuildAcquisitionPlan(signals) if plan.Mode != ModeFallback { t.Fatalf("expected fallback mode, got %q", plan.Mode) } plan.PlanBPaths = append(plan.PlanBPaths, "/redfish/v1/Systems/1/Oem/TestPlanB") resolved := ResolveAcquisitionPlan(match, plan, DiscoveredResources{ SystemPaths: []string{"/redfish/v1/Systems/1"}, }, signals) if !containsJoinedPath(joinResolvedPaths(resolved.SeedPaths), "/redfish/v1/Systems/1/Oem/TestPlanB") { t.Fatal("expected fallback resolved seeds to include plan-b path") } } func TestResolveAcquisitionPlan_MSIRefinesDiscoveredGPUChassis(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Micro-Star International Co., Ltd.", ResourceHints: []string{"/redfish/v1/Chassis/GPU1", "/redfish/v1/Chassis/GPU4/Sensors"}, } match := MatchProfiles(signals) plan := BuildAcquisitionPlan(signals) resolved := ResolveAcquisitionPlan(match, plan, DiscoveredResources{ ChassisPaths: []string{"/redfish/v1/Chassis/1", "/redfish/v1/Chassis/GPU1", "/redfish/v1/Chassis/GPU4"}, }, signals) joinedSeeds := joinResolvedPaths(resolved.SeedPaths) joinedCritical := joinResolvedPaths(resolved.CriticalPaths) if !containsJoinedPath(joinedSeeds, "/redfish/v1/Chassis/GPU1") || !containsJoinedPath(joinedSeeds, "/redfish/v1/Chassis/GPU4") { t.Fatal("expected MSI refinement to add discovered GPU chassis seed paths") } if containsJoinedPath(joinedSeeds, "/redfish/v1/Chassis/GPU2") { t.Fatal("did not expect undiscovered MSI GPU chassis in resolved seeds") } if !containsJoinedPath(joinedCritical, "/redfish/v1/Chassis/GPU1/Sensors") || !containsJoinedPath(joinedCritical, "/redfish/v1/Chassis/GPU4/Sensors") { t.Fatal("expected MSI refinement to add discovered GPU sensor critical paths") } if containsJoinedPath(joinedCritical, "/redfish/v1/Chassis/GPU3/Sensors") { t.Fatal("did not expect undiscovered MSI GPU sensor critical path") } } func TestResolveAcquisitionPlan_HGXRefinesDiscoveredBaseboardSystems(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Supermicro", SystemModel: "SYS-821GE-TNHR", ChassisModel: "HGX B200", ResourceHints: []string{ "/redfish/v1/Systems/HGX_Baseboard_0", "/redfish/v1/Systems/HGX_Baseboard_0/Processors", "/redfish/v1/Systems/1", }, } match := MatchProfiles(signals) plan := BuildAcquisitionPlan(signals) resolved := ResolveAcquisitionPlan(match, plan, DiscoveredResources{ SystemPaths: []string{"/redfish/v1/Systems/1", "/redfish/v1/Systems/HGX_Baseboard_0"}, }, signals) joinedSeeds := joinResolvedPaths(resolved.SeedPaths) joinedCritical := joinResolvedPaths(resolved.CriticalPaths) if !containsJoinedPath(joinedSeeds, "/redfish/v1/Systems/HGX_Baseboard_0") || !containsJoinedPath(joinedSeeds, "/redfish/v1/Systems/HGX_Baseboard_0/Processors") { t.Fatal("expected HGX refinement to add discovered baseboard system paths") } if !containsJoinedPath(joinedCritical, "/redfish/v1/Systems/HGX_Baseboard_0") || !containsJoinedPath(joinedCritical, "/redfish/v1/Systems/HGX_Baseboard_0/Processors") { t.Fatal("expected HGX refinement to add discovered baseboard critical paths") } if containsJoinedPath(joinedSeeds, "/redfish/v1/Systems/HGX_Baseboard_1") { t.Fatal("did not expect undiscovered HGX baseboard system path") } } func TestResolveAcquisitionPlan_SupermicroRefinesFirmwareInventoryFromHint(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Supermicro", ResourceHints: []string{ "/redfish/v1/UpdateService/Oem/Supermicro/FirmwareInventory", "/redfish/v1/Managers/1/Oem/Supermicro/FanMode", }, } match := MatchProfiles(signals) plan := BuildAcquisitionPlan(signals) resolved := ResolveAcquisitionPlan(match, plan, DiscoveredResources{ ManagerPaths: []string{"/redfish/v1/Managers/1"}, }, signals) joinedCritical := joinResolvedPaths(resolved.CriticalPaths) if !containsJoinedPath(joinedCritical, "/redfish/v1/UpdateService/Oem/Supermicro/FirmwareInventory") { t.Fatal("expected Supermicro refinement to add firmware inventory critical path") } if !containsJoinedPath(joinResolvedPaths(resolved.Plan.PlanBPaths), "/redfish/v1/UpdateService/Oem/Supermicro/FirmwareInventory") { t.Fatal("expected Supermicro refinement to add firmware inventory plan-b path") } } func TestResolveAcquisitionPlan_DellRefinesDiscoveredIDRACManager(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Dell Inc.", ServiceRootProduct: "iDRAC Redfish Service", } match := MatchProfiles(signals) plan := BuildAcquisitionPlan(signals) resolved := ResolveAcquisitionPlan(match, plan, DiscoveredResources{ ManagerPaths: []string{"/redfish/v1/Managers/1", "/redfish/v1/Managers/iDRAC.Embedded.1"}, }, signals) joinedSeeds := joinResolvedPaths(resolved.SeedPaths) joinedCritical := joinResolvedPaths(resolved.CriticalPaths) if !containsJoinedPath(joinedSeeds, "/redfish/v1/Managers/iDRAC.Embedded.1") { t.Fatal("expected Dell refinement to add discovered iDRAC manager seed path") } if !containsJoinedPath(joinedCritical, "/redfish/v1/Managers/iDRAC.Embedded.1") { t.Fatal("expected Dell refinement to add discovered iDRAC manager critical path") } } func TestBuildAnalysisDirectives_SupermicroEnablesVendorStorageFallbacks(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Supermicro", SystemModel: "SYS-821GE", } match := MatchProfiles(signals) plan := ResolveAnalysisPlan(match, map[string]interface{}{ "/redfish/v1/Chassis/NVMeSSD.1.StorageBackplane/Drives": map[string]interface{}{}, }, DiscoveredResources{}, signals) directives := plan.Directives if !directives.EnableSupermicroNVMeBackplane { t.Fatal("expected supermicro nvme backplane fallback") } } func joinResolvedPaths(paths []string) string { return "\n" + strings.Join(paths, "\n") + "\n" } func containsJoinedPath(joined, want string) bool { return strings.Contains(joined, "\n"+want+"\n") } func TestBuildAnalysisDirectives_HGXEnablesGPUFallbacks(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Supermicro", SystemModel: "SYS-821GE-TNHR", ChassisModel: "HGX B200", ResourceHints: []string{"/redfish/v1/Systems/HGX_Baseboard_0", "/redfish/v1/Chassis/HGX_Chassis_0/PCIeDevices/GPU_SXM_1"}, } match := MatchProfiles(signals) plan := ResolveAnalysisPlan(match, map[string]interface{}{ "/redfish/v1/Systems/HGX_Baseboard_0/Processors/GPU_SXM_1": map[string]interface{}{"ProcessorType": "GPU"}, "/redfish/v1/Chassis/HGX_Chassis_0/PCIeDevices/GPU_SXM_1": map[string]interface{}{}, }, DiscoveredResources{ SystemPaths: []string{"/redfish/v1/Systems/HGX_Baseboard_0"}, }, signals) directives := plan.Directives if !directives.EnableProcessorGPUFallback { t.Fatal("expected processor GPU fallback for hgx profile") } if !directives.EnableProcessorGPUChassisAlias { t.Fatal("expected processor GPU chassis alias resolution for hgx profile") } if !directives.EnableGenericGraphicsControllerDedup { t.Fatal("expected graphics-controller dedup for hgx profile") } } func TestBuildAnalysisDirectives_MSIEnablesMSIChassisLookup(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Micro-Star International Co., Ltd.", } match := MatchProfiles(signals) plan := ResolveAnalysisPlan(match, map[string]interface{}{ "/redfish/v1/Systems/1/Processors/GPU1": map[string]interface{}{"ProcessorType": "GPU"}, "/redfish/v1/Chassis/GPU1": map[string]interface{}{}, }, DiscoveredResources{ SystemPaths: []string{"/redfish/v1/Systems/1"}, ChassisPaths: []string{"/redfish/v1/Chassis/GPU1"}, }, signals) directives := plan.Directives if !directives.EnableMSIProcessorGPUChassisLookup { t.Fatal("expected MSI processor GPU chassis lookup") } } func TestBuildAnalysisDirectives_SupermicroEnablesStorageRecovery(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Supermicro", } match := MatchProfiles(signals) plan := ResolveAnalysisPlan(match, map[string]interface{}{ "/redfish/v1/Chassis/1/Drives": map[string]interface{}{}, "/redfish/v1/Systems/1/Storage/IntelVROC": map[string]interface{}{}, "/redfish/v1/Systems/1/Storage/IntelVROC/Drives": map[string]interface{}{}, }, DiscoveredResources{}, signals) directives := plan.Directives if !directives.EnableStorageEnclosureRecovery { t.Fatal("expected storage enclosure recovery for supermicro") } if !directives.EnableKnownStorageControllerRecovery { t.Fatal("expected known storage controller recovery for supermicro") } } func TestMatchProfiles_LenovoXCCSelectsMatchedModeAndExcludesSensors(t *testing.T) { match := MatchProfiles(MatchSignals{ SystemManufacturer: "Lenovo", ChassisManufacturer: "Lenovo", OEMNamespaces: []string{"Lenovo"}, }) if match.Mode != ModeMatched { t.Fatalf("expected matched mode, got %q", match.Mode) } found := false for _, profile := range match.Profiles { if profile.Name() == "lenovo" { found = true break } } if !found { t.Fatal("expected lenovo profile to be selected") } // Verify the acquisition plan excludes noisy Lenovo-specific snapshot paths. plan := BuildAcquisitionPlan(MatchSignals{ SystemManufacturer: "Lenovo", ChassisManufacturer: "Lenovo", OEMNamespaces: []string{"Lenovo"}, }) wantExcluded := []string{"/Sensors/", "/Oem/Lenovo/LEDs/", "/Oem/Lenovo/Slots/"} for _, want := range wantExcluded { found := false for _, ex := range plan.Tuning.SnapshotExcludeContains { if ex == want { found = true break } } if !found { t.Errorf("expected SnapshotExcludeContains to include %q, got %v", want, plan.Tuning.SnapshotExcludeContains) } } } func TestMatchProfiles_OrderingIsDeterministic(t *testing.T) { signals := MatchSignals{ SystemManufacturer: "Micro-Star International Co., Ltd.", ResourceHints: []string{"/redfish/v1/Chassis/GPU1"}, } first := MatchProfiles(signals) second := MatchProfiles(signals) if len(first.Profiles) != len(second.Profiles) { t.Fatalf("profile stack size differs across calls: %d vs %d", len(first.Profiles), len(second.Profiles)) } for i := range first.Profiles { if first.Profiles[i].Name() != second.Profiles[i].Name() { t.Fatalf("profile ordering differs at index %d: %q vs %q", i, first.Profiles[i].Name(), second.Profiles[i].Name()) } } } func TestMatchProfiles_FallbackOrderingIsDeterministic(t *testing.T) { signals := MatchSignals{ServiceRootProduct: "Unknown Redfish"} first := MatchProfiles(signals) second := MatchProfiles(signals) if first.Mode != ModeFallback || second.Mode != ModeFallback { t.Fatalf("expected fallback mode in both calls") } if len(first.Profiles) != len(second.Profiles) { t.Fatalf("fallback profile stack size differs: %d vs %d", len(first.Profiles), len(second.Profiles)) } for i := range first.Profiles { if first.Profiles[i].Name() != second.Profiles[i].Name() { t.Fatalf("fallback profile ordering differs at index %d: %q vs %q", i, first.Profiles[i].Name(), second.Profiles[i].Name()) } } } func TestMatchProfiles_FallbackOnlySelectsSafeProfiles(t *testing.T) { match := MatchProfiles(MatchSignals{ServiceRootProduct: "Unknown Generic Redfish Server"}) if match.Mode != ModeFallback { t.Fatalf("expected fallback mode, got %q", match.Mode) } for _, profile := range match.Profiles { if !profile.SafeForFallback() { t.Fatalf("fallback mode included non-safe profile %q", profile.Name()) } } } func TestBuildAnalysisDirectives_GenericMatchedKeepsFallbacksDisabled(t *testing.T) { match := MatchResult{ Mode: ModeMatched, Profiles: []Profile{genericProfile()}, } directives := ResolveAnalysisPlan(match, nil, DiscoveredResources{}, MatchSignals{}).Directives if directives.EnableProcessorGPUFallback { t.Fatal("did not expect processor GPU fallback for generic matched profile") } if directives.EnableSupermicroNVMeBackplane { t.Fatal("did not expect supermicro nvme fallback for generic matched profile") } if directives.EnableGenericGraphicsControllerDedup { t.Fatal("did not expect generic graphics-controller dedup for generic matched profile") } }