@@ -23,6 +23,7 @@ package controller
2323import (
2424 "context"
2525 "fmt"
26+ "testing"
2627 "time"
2728
2829 "github.com/NVIDIA/skyhook/api/v1alpha1"
@@ -880,34 +881,34 @@ var _ = Describe("skyhook controller tests", func() {
880881
881882 // Test 1: Deterministic behavior (same inputs = same output)
882883 prefix1 := createNamePrefix (skyhook .Name , package1 .Name , package1 .Version , string (v1alpha1 .StageApply ))
883- name1 := generatePodName ( prefix1 , nodeName )
884- name2 := generatePodName ( prefix1 , nodeName )
884+ name1 := generateSafeName ( 63 , prefix1 , nodeName )
885+ name2 := generateSafeName ( 63 , prefix1 , nodeName )
885886 Expect (name1 ).To (Equal (name2 ), "Generated pod names should be deterministic" )
886887
887888 // Test 2: Uniqueness with different inputs
888889 // Different stage
889890 prefixApply := createNamePrefix (skyhook .Name , package1 .Name , package1 .Version , string (v1alpha1 .StageApply ))
890891 prefixConfig := createNamePrefix (skyhook .Name , package1 .Name , package1 .Version , string (v1alpha1 .StageConfig ))
891- nameApply := generatePodName ( prefixApply , nodeName )
892- nameConfig := generatePodName ( prefixConfig , nodeName )
892+ nameApply := generateSafeName ( 63 , prefixApply , nodeName )
893+ nameConfig := generateSafeName ( 63 , prefixConfig , nodeName )
893894 Expect (nameApply ).NotTo (Equal (nameConfig ), "Different stages should produce different pod names" )
894895
895896 // Different package version
896897 prefix2 := createNamePrefix (skyhook .Name , package2 .Name , package2 .Version , string (v1alpha1 .StageApply ))
897- nameVersion1 := generatePodName ( prefix1 , nodeName )
898- nameVersion2 := generatePodName ( prefix2 , nodeName )
898+ nameVersion1 := generateSafeName ( 63 , prefix1 , nodeName )
899+ nameVersion2 := generateSafeName ( 63 , prefix2 , nodeName )
899900 Expect (nameVersion1 ).NotTo (Equal (nameVersion2 ), "Different package versions should produce different pod names" )
900901
901902 // Different node
902- nameNode1 := generatePodName ( prefix1 , nodeName )
903- nameNode2 := generatePodName ( prefix1 , nodeName2 )
903+ nameNode1 := generateSafeName ( 63 , prefix1 , nodeName )
904+ nameNode2 := generateSafeName ( 63 , prefix1 , nodeName2 )
904905 Expect (nameNode1 ).NotTo (Equal (nameNode2 ), "Different nodes should produce different pod names" )
905906
906907 // Test for uninstall pods with timestamp
907908 uninstallPrefix1 := fmt .Sprintf ("%s-uninstall-123456789" , prefixApply )
908909 uninstallPrefix2 := fmt .Sprintf ("%s-uninstall-987654321" , prefixApply )
909- uninstallName1 := generatePodName ( uninstallPrefix1 , nodeName )
910- uninstallName2 := generatePodName ( uninstallPrefix2 , nodeName )
910+ uninstallName1 := generateSafeName ( 63 , uninstallPrefix1 , nodeName )
911+ uninstallName2 := generateSafeName ( 63 , uninstallPrefix2 , nodeName )
911912 Expect (uninstallName1 ).NotTo (Equal (uninstallName2 ), "Uninstall pods with different timestamps should have different names" )
912913 Expect (uninstallName1 ).NotTo (Equal (nameApply ), "Uninstall pod name should be different from regular pod name" )
913914
@@ -916,7 +917,7 @@ var _ = Describe("skyhook controller tests", func() {
916917 longPackageName := "this-is-a-very-long-package-name-that-also-exceeds-kubernetes-naming-limits"
917918 longPackageVersion := "1.2.3.4.5.6.7.8.9.10"
918919 longPrefix := createNamePrefix (longSkyhookName , longPackageName , longPackageVersion , string (v1alpha1 .StageApply ))
919- longName := generatePodName ( longPrefix , "node1" )
920+ longName := generateSafeName ( 63 , longPrefix , "node1" )
920921 Expect (len (longName )).To (BeNumerically ("<=" , 63 ), "Pod name should not exceed Kubernetes 63 character limit" )
921922 Expect (longName ).To (MatchRegexp (`-[0-9a-f]+$` ), "Pod name should end with a hash component" )
922923 })
@@ -984,4 +985,127 @@ var _ = Describe("skyhook controller tests", func() {
984985 matches = operator .PodMatchesPackage (testPackage , * interruptPod , testSkyhook , testStage )
985986 Expect (matches ).To (BeTrue (), "PodMatchesPackage should recognize the interrupt pod it created" )
986987 })
988+
989+ It ("should generate valid volume names" , func () {
990+ tests := []struct {
991+ name string
992+ prefix string
993+ nodeName string
994+ expectedLen int
995+ shouldMatch string
996+ description string
997+ }{
998+ {
999+ name : "short name" ,
1000+ prefix : "metadata" ,
1001+ nodeName : "node1" ,
1002+ expectedLen : 23 , // "metadata-node1-" + 8 char hash
1003+ description : "should handle short names" ,
1004+ },
1005+ {
1006+ name : "very long node name" ,
1007+ prefix : "metadata" ,
1008+ nodeName : "very-long-node-name-that-exceeds-kubernetes-limits-and-needs-to-be-truncated-to-something-shorter" ,
1009+ expectedLen : 63 ,
1010+ description : "should handle long names by hashing" ,
1011+ },
1012+ {
1013+ name : "consistent hashing" ,
1014+ prefix : "metadata" ,
1015+ nodeName : "node1" ,
1016+ shouldMatch : generateSafeName (63 , "metadata" , "node1" ),
1017+ description : "should generate consistent names for the same input" ,
1018+ },
1019+ }
1020+
1021+ for _ , tt := range tests {
1022+ result := generateSafeName (63 , tt .prefix , tt .nodeName )
1023+
1024+ if tt .expectedLen > 0 {
1025+ Expect (len (result )).To (Equal (tt .expectedLen ), tt .description )
1026+ }
1027+ if tt .shouldMatch != "" {
1028+ Expect (result ).To (Equal (tt .shouldMatch ), tt .description )
1029+ }
1030+ Expect (len (result )).To (BeNumerically ("<=" , 63 ), "volume name should never exceed 63 characters" )
1031+ Expect (result ).To (MatchRegexp (`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$` ), "volume name should match kubernetes naming requirements" )
1032+ }
1033+ })
1034+
1035+ It ("should generate valid configmap names" , func () {
1036+ tests := []struct {
1037+ name string
1038+ skyhookName string
1039+ nodeName string
1040+ expectedLen int
1041+ shouldMatch string
1042+ description string
1043+ }{
1044+ {
1045+ name : "short names" ,
1046+ skyhookName : "skyhook1" ,
1047+ nodeName : "node1" ,
1048+ expectedLen : 32 , // "skyhook1-node1-metadata-" + 8 char hash
1049+ description : "should handle short names" ,
1050+ },
1051+ {
1052+ name : "very long names" ,
1053+ skyhookName : "very-long-skyhook-name" ,
1054+ nodeName : "very-long-node-name-that-exceeds-kubernetes-limits-and-needs-to-be-truncated" ,
1055+ expectedLen : 63 ,
1056+ description : "should handle long names by truncating and hashing" ,
1057+ },
1058+ {
1059+ name : "consistent hashing" ,
1060+ skyhookName : "skyhook1" ,
1061+ nodeName : "node1" ,
1062+ shouldMatch : generateSafeName (63 , "skyhook1" , "node1" , "metadata" ),
1063+ description : "should generate consistent names for the same input" ,
1064+ },
1065+ {
1066+ name : "handles dots in names" ,
1067+ skyhookName : "skyhook.1" ,
1068+ nodeName : "node.1" ,
1069+ expectedLen : 34 ,
1070+ description : "should handle dots in names consistently" ,
1071+ },
1072+ }
1073+
1074+ for _ , tt := range tests {
1075+ result := generateSafeName (63 , tt .skyhookName , tt .nodeName , "metadata" )
1076+
1077+ if tt .expectedLen > 0 {
1078+ Expect (len (result )).To (Equal (tt .expectedLen ), tt .description )
1079+ }
1080+ if tt .shouldMatch != "" {
1081+ Expect (result ).To (Equal (tt .shouldMatch ), tt .description )
1082+ }
1083+ Expect (len (result )).To (BeNumerically ("<=" , 63 ), "configmap name should never exceed 63 characters" )
1084+ Expect (result ).To (MatchRegexp (`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$` ), "configmap name should match kubernetes naming requirements" )
1085+ }
1086+ })
9871087})
1088+
1089+ func TestGenerateValidPodNames (t * testing.T ) {
1090+ g := NewWithT (t )
1091+
1092+ // Test short name
1093+ name := generateSafeName (63 , "test" , "node1" )
1094+ g .Expect (len (name )).To (Equal (19 )) // "test-node1-" + 8 char hash
1095+ g .Expect (name ).To (MatchRegexp (`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$` ))
1096+
1097+ // Test very long name
1098+ name = generateSafeName (63 , "test-very-long-name-that-should-be-truncated" , "node1" )
1099+ g .Expect (len (name )).To (Equal (59 ))
1100+ g .Expect (name ).To (MatchRegexp (`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$` ))
1101+
1102+ // Test consistent hashing
1103+ name1 := generateSafeName (63 , "test" , "node1" )
1104+ name2 := generateSafeName (63 , "test" , "node1" )
1105+ g .Expect (name1 ).To (Equal (name2 ))
1106+
1107+ // Test dots in name
1108+ name = generateSafeName (63 , "test.name" , "node.1" )
1109+ g .Expect (name ).To (MatchRegexp (`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$` ))
1110+ g .Expect (len (name )).To (Equal (25 )) // "test-name-node-1-" + 8 char hash
1111+ }
0 commit comments