@@ -543,6 +543,8 @@ impl CredentialKey {
543543
544544#[ cfg( test) ]
545545mod tests {
546+ use carbide_test_support:: { Check , check_values} ;
547+
546548 use super :: * ;
547549 use crate :: test_support:: credentials:: TestCredentialManager ;
548550
@@ -666,145 +668,255 @@ mod tests {
666668 let rack_id = RackId :: new ( "rack-01" ) ;
667669 let mac: MacAddress = MacAddress :: new ( [ 0xAA , 0xBB , 0xCC , 0xDD , 0xEE , 0xFF ] ) ;
668670
669- let cases: Vec < ( CredentialKey , & str ) > = vec ! [
670- ( CredentialKey :: DpuHbn { machine_id } , "machines/" ) ,
671- (
672- CredentialKey :: DpuRedfish {
673- credential_type: CredentialType :: DpuHardwareDefault ,
671+ // Each row is a key and the path prefix its `to_key_str()` must carry. A
672+ // path is well-formed when it is non-empty, has no leading or trailing
673+ // slash, and starts with that prefix.
674+ struct Row {
675+ key : CredentialKey ,
676+ expected_prefix : & ' static str ,
677+ }
678+
679+ // The four invariants of a well-formed key path, checked as named fields
680+ // rather than folded into one bool so a failing row names the invariant
681+ // it broke. A well-formed path holds all four.
682+ #[ derive( Debug , PartialEq ) ]
683+ struct PathChecks {
684+ non_empty : bool ,
685+ no_leading_slash : bool ,
686+ no_trailing_slash : bool ,
687+ has_expected_prefix : bool ,
688+ }
689+
690+ impl PathChecks {
691+ const fn all_hold ( ) -> Self {
692+ Self {
693+ non_empty : true ,
694+ no_leading_slash : true ,
695+ no_trailing_slash : true ,
696+ has_expected_prefix : true ,
697+ }
698+ }
699+ }
700+
701+ check_values (
702+ [
703+ Check {
704+ scenario : "dpu hbn" ,
705+ input : Row {
706+ key : CredentialKey :: DpuHbn { machine_id } ,
707+ expected_prefix : "machines/" ,
708+ } ,
709+ expect : PathChecks :: all_hold ( ) ,
674710 } ,
675- "machines/all_dpus/" ,
676- ) ,
677- (
678- CredentialKey :: DpuRedfish {
679- credential_type: CredentialType :: SiteDefault ,
711+ Check {
712+ scenario : "dpu redfish hardware default" ,
713+ input : Row {
714+ key : CredentialKey :: DpuRedfish {
715+ credential_type : CredentialType :: DpuHardwareDefault ,
716+ } ,
717+ expected_prefix : "machines/all_dpus/" ,
718+ } ,
719+ expect : PathChecks :: all_hold ( ) ,
680720 } ,
681- "machines/all_dpus/" ,
682- ) ,
683- (
684- CredentialKey :: HostRedfish {
685- credential_type: CredentialType :: HostHardwareDefault {
686- vendor: bmc_vendor:: BMCVendor :: Nvidia ,
721+ Check {
722+ scenario : "dpu redfish site default" ,
723+ input : Row {
724+ key : CredentialKey :: DpuRedfish {
725+ credential_type : CredentialType :: SiteDefault ,
726+ } ,
727+ expected_prefix : "machines/all_dpus/" ,
687728 } ,
729+ expect : PathChecks :: all_hold ( ) ,
688730 } ,
689- "machines/all_hosts/" ,
690- ) ,
691- (
692- CredentialKey :: HostRedfish {
693- credential_type: CredentialType :: SiteDefault ,
731+ Check {
732+ scenario : "host redfish hardware default" ,
733+ input : Row {
734+ key : CredentialKey :: HostRedfish {
735+ credential_type : CredentialType :: HostHardwareDefault {
736+ vendor : bmc_vendor:: BMCVendor :: Nvidia ,
737+ } ,
738+ } ,
739+ expected_prefix : "machines/all_hosts/" ,
740+ } ,
741+ expect : PathChecks :: all_hold ( ) ,
694742 } ,
695- "machines/all_hosts/" ,
696- ) ,
697- (
698- CredentialKey :: UfmAuth {
699- fabric: "test-fabric" . to_string( ) ,
743+ Check {
744+ scenario : "host redfish site default" ,
745+ input : Row {
746+ key : CredentialKey :: HostRedfish {
747+ credential_type : CredentialType :: SiteDefault ,
748+ } ,
749+ expected_prefix : "machines/all_hosts/" ,
750+ } ,
751+ expect : PathChecks :: all_hold ( ) ,
700752 } ,
701- "ufm/" ,
702- ) ,
703- (
704- CredentialKey :: DpuUefi {
705- credential_type: CredentialType :: DpuHardwareDefault ,
753+ Check {
754+ scenario : "ufm auth" ,
755+ input : Row {
756+ key : CredentialKey :: UfmAuth {
757+ fabric : "test-fabric" . to_string ( ) ,
758+ } ,
759+ expected_prefix : "ufm/" ,
760+ } ,
761+ expect : PathChecks :: all_hold ( ) ,
706762 } ,
707- "machines/all_dpus/" ,
708- ) ,
709- (
710- CredentialKey :: DpuUefi {
711- credential_type: CredentialType :: SiteDefault ,
763+ Check {
764+ scenario : "dpu uefi hardware default" ,
765+ input : Row {
766+ key : CredentialKey :: DpuUefi {
767+ credential_type : CredentialType :: DpuHardwareDefault ,
768+ } ,
769+ expected_prefix : "machines/all_dpus/" ,
770+ } ,
771+ expect : PathChecks :: all_hold ( ) ,
712772 } ,
713- "machines/all_dpus/" ,
714- ) ,
715- (
716- CredentialKey :: HostUefi {
717- credential_type: CredentialType :: SiteDefault ,
773+ Check {
774+ scenario : "dpu uefi site default" ,
775+ input : Row {
776+ key : CredentialKey :: DpuUefi {
777+ credential_type : CredentialType :: SiteDefault ,
778+ } ,
779+ expected_prefix : "machines/all_dpus/" ,
780+ } ,
781+ expect : PathChecks :: all_hold ( ) ,
718782 } ,
719- "machines/all_hosts/" ,
720- ) ,
721- (
722- CredentialKey :: BmcCredentials {
723- credential_type: BmcCredentialType :: SiteWideRoot ,
783+ Check {
784+ scenario : "host uefi site default" ,
785+ input : Row {
786+ key : CredentialKey :: HostUefi {
787+ credential_type : CredentialType :: SiteDefault ,
788+ } ,
789+ expected_prefix : "machines/all_hosts/" ,
790+ } ,
791+ expect : PathChecks :: all_hold ( ) ,
724792 } ,
725- "machines/bmc/" ,
726- ) ,
727- (
728- CredentialKey :: BmcCredentials {
729- credential_type: BmcCredentialType :: BmcRoot {
730- bmc_mac_address: mac,
793+ Check {
794+ scenario : "bmc site wide root" ,
795+ input : Row {
796+ key : CredentialKey :: BmcCredentials {
797+ credential_type : BmcCredentialType :: SiteWideRoot ,
798+ } ,
799+ expected_prefix : "machines/bmc/" ,
731800 } ,
801+ expect : PathChecks :: all_hold ( ) ,
732802 } ,
733- "machines/bmc/" ,
734- ) ,
735- (
736- CredentialKey :: BmcCredentials {
737- credential_type: BmcCredentialType :: BmcForgeAdmin {
738- bmc_mac_address: mac,
803+ Check {
804+ scenario : "bmc root" ,
805+ input : Row {
806+ key : CredentialKey :: BmcCredentials {
807+ credential_type : BmcCredentialType :: BmcRoot {
808+ bmc_mac_address : mac,
809+ } ,
810+ } ,
811+ expected_prefix : "machines/bmc/" ,
739812 } ,
813+ expect : PathChecks :: all_hold ( ) ,
740814 } ,
741- "machines/bmc/" ,
742- ) ,
743- (
744- CredentialKey :: NicLockdownIkm {
745- credential_type: NicLockdownIkm :: SiteWide { version: 0 } ,
815+ Check {
816+ scenario : "bmc forge admin" ,
817+ input : Row {
818+ key : CredentialKey :: BmcCredentials {
819+ credential_type : BmcCredentialType :: BmcForgeAdmin {
820+ bmc_mac_address : mac,
821+ } ,
822+ } ,
823+ expected_prefix : "machines/bmc/" ,
824+ } ,
825+ expect : PathChecks :: all_hold ( ) ,
746826 } ,
747- "machines/nic_lockdown_ikm/" ,
748- ) ,
749- (
750- CredentialKey :: ExtensionService {
751- service_id: "svc1" . to_string( ) ,
752- version: "v1" . to_string( ) ,
827+ Check {
828+ scenario : "nic lockdown ikm" ,
829+ input : Row {
830+ key : CredentialKey :: NicLockdownIkm {
831+ credential_type : NicLockdownIkm :: SiteWide { version : 0 } ,
832+ } ,
833+ expected_prefix : "machines/nic_lockdown_ikm/" ,
834+ } ,
835+ expect : PathChecks :: all_hold ( ) ,
753836 } ,
754- "machines/extension-services/" ,
755- ) ,
756- (
757- CredentialKey :: NmxM {
758- nmxm_id: "nmxm1" . to_string( ) ,
837+ Check {
838+ scenario : "extension service" ,
839+ input : Row {
840+ key : CredentialKey :: ExtensionService {
841+ service_id : "svc1" . to_string ( ) ,
842+ version : "v1" . to_string ( ) ,
843+ } ,
844+ expected_prefix : "machines/extension-services/" ,
845+ } ,
846+ expect : PathChecks :: all_hold ( ) ,
759847 } ,
760- "nmxm/" ,
761- ) ,
762- (
763- CredentialKey :: SwitchNvosAdmin {
764- bmc_mac_address: mac,
848+ Check {
849+ scenario : "nmxm" ,
850+ input : Row {
851+ key : CredentialKey :: NmxM {
852+ nmxm_id : "nmxm1" . to_string ( ) ,
853+ } ,
854+ expected_prefix : "nmxm/" ,
855+ } ,
856+ expect : PathChecks :: all_hold ( ) ,
765857 } ,
766- "switch_nvos/" ,
767- ) ,
768- (
769- CredentialKey :: MqttAuth {
770- credential_type: MqttCredentialType :: Dpa ,
858+ Check {
859+ scenario : "switch nvos admin" ,
860+ input : Row {
861+ key : CredentialKey :: SwitchNvosAdmin {
862+ bmc_mac_address : mac,
863+ } ,
864+ expected_prefix : "switch_nvos/" ,
865+ } ,
866+ expect : PathChecks :: all_hold ( ) ,
771867 } ,
772- "mqtt/" ,
773- ) ,
774- (
775- CredentialKey :: MqttAuth {
776- credential_type: MqttCredentialType :: DsxExchangeEventBus ,
868+ Check {
869+ scenario : "mqtt dpa" ,
870+ input : Row {
871+ key : CredentialKey :: MqttAuth {
872+ credential_type : MqttCredentialType :: Dpa ,
873+ } ,
874+ expected_prefix : "mqtt/" ,
875+ } ,
876+ expect : PathChecks :: all_hold ( ) ,
777877 } ,
778- "mqtt/" ,
779- ) ,
780- (
781- CredentialKey :: MqttAuth {
782- credential_type: MqttCredentialType :: DsxExchangeConsumer ,
878+ Check {
879+ scenario : "mqtt dsx exchange event bus" ,
880+ input : Row {
881+ key : CredentialKey :: MqttAuth {
882+ credential_type : MqttCredentialType :: DsxExchangeEventBus ,
883+ } ,
884+ expected_prefix : "mqtt/" ,
885+ } ,
886+ expect : PathChecks :: all_hold ( ) ,
783887 } ,
784- "mqtt/" ,
785- ) ,
786- (
787- CredentialKey :: RackMaintenanceAccessToken { rack_id } ,
788- "racks/" ,
789- ) ,
790- ] ;
791-
792- for ( key, expected_prefix) in & cases {
793- let path = key. to_key_str ( ) ;
794- assert ! ( !path. is_empty( ) , "{key:?} produced an empty path" ) ;
795- assert ! (
796- !path. starts_with( '/' ) ,
797- "{key:?} path {path:?} should not start with /"
798- ) ;
799- assert ! (
800- !path. ends_with( '/' ) ,
801- "{key:?} path {path:?} should not end with /"
802- ) ;
803- assert ! (
804- path. starts_with( expected_prefix) ,
805- "{key:?} path {path:?} should start with {expected_prefix:?}"
806- ) ;
807- }
888+ Check {
889+ scenario : "mqtt dsx exchange consumer" ,
890+ input : Row {
891+ key : CredentialKey :: MqttAuth {
892+ credential_type : MqttCredentialType :: DsxExchangeConsumer ,
893+ } ,
894+ expected_prefix : "mqtt/" ,
895+ } ,
896+ expect : PathChecks :: all_hold ( ) ,
897+ } ,
898+ Check {
899+ scenario : "rack maintenance access token" ,
900+ input : Row {
901+ key : CredentialKey :: RackMaintenanceAccessToken { rack_id } ,
902+ expected_prefix : "racks/" ,
903+ } ,
904+ expect : PathChecks :: all_hold ( ) ,
905+ } ,
906+ ] ,
907+ |Row {
908+ key,
909+ expected_prefix,
910+ } | {
911+ let path = key. to_key_str ( ) ;
912+ PathChecks {
913+ non_empty : !path. is_empty ( ) ,
914+ no_leading_slash : !path. starts_with ( '/' ) ,
915+ no_trailing_slash : !path. ends_with ( '/' ) ,
916+ has_expected_prefix : path. starts_with ( expected_prefix) ,
917+ }
918+ } ,
919+ ) ;
808920 }
809921
810922 // Verifies that every CredentialKey's to_key_str()
0 commit comments