use generic Set in api

Signed-off-by: bzsuni <bingzhe.sun@daocloud.io>
This commit is contained in:
bzsuni 2023-09-25 19:04:08 +08:00
parent c6bb90aeea
commit aa9b2b1696
10 changed files with 90 additions and 90 deletions

View File

@ -67,12 +67,12 @@ func TestWarnings(t *testing.T) {
for _, tc := range testcases {
t.Run("podspec_"+tc.name, func(t *testing.T) {
actual := sets.NewString(GetWarningsForRuntimeClass(tc.template)...)
expected := sets.NewString(tc.expected...)
for _, missing := range expected.Difference(actual).List() {
actual := sets.New[string](GetWarningsForRuntimeClass(tc.template)...)
expected := sets.New[string](tc.expected...)
for _, missing := range sets.List[string](expected.Difference(actual)) {
t.Errorf("missing: %s", missing)
}
for _, extra := range actual.Difference(expected).List() {
for _, extra := range sets.List[string](actual.Difference(expected)) {
t.Errorf("extra: %s", extra)
}
})

View File

@ -298,12 +298,12 @@ func TestWarnings(t *testing.T) {
for _, tc := range testcases {
t.Run("podspec_"+tc.name, func(t *testing.T) {
actual := sets.NewString(GetWarningsForPersistentVolume(tc.template)...)
expected := sets.NewString(tc.expected...)
for _, missing := range expected.Difference(actual).List() {
actual := sets.New[string](GetWarningsForPersistentVolume(tc.template)...)
expected := sets.New[string](tc.expected...)
for _, missing := range sets.List[string](expected.Difference(actual)) {
t.Errorf("missing: %s", missing)
}
for _, extra := range actual.Difference(expected).List() {
for _, extra := range sets.List[string](actual.Difference(expected)) {
t.Errorf("extra: %s", extra)
}
})

View File

@ -571,12 +571,12 @@ func TestWarnings(t *testing.T) {
for _, tc := range testcases {
t.Run("pvcspec_"+tc.name, func(t *testing.T) {
actual := sets.NewString(GetWarningsForPersistentVolumeClaim(tc.template)...)
expected := sets.NewString(tc.expected...)
for _, missing := range expected.Difference(actual).List() {
actual := sets.New[string](GetWarningsForPersistentVolumeClaim(tc.template)...)
expected := sets.New[string](tc.expected...)
for _, missing := range sets.List[string](expected.Difference(actual)) {
t.Errorf("missing: %s", missing)
}
for _, extra := range actual.Difference(expected).List() {
for _, extra := range sets.List[string](actual.Difference(expected)) {
t.Errorf("extra: %s", extra)
}
})

View File

@ -290,19 +290,19 @@ func TestPodSecrets(t *testing.T) {
Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.SecretKeyRef"}}}}}}}},
},
}
extractedNames := sets.NewString()
extractedNames := sets.New[string]()
VisitPodSecretNames(pod, func(name string) bool {
extractedNames.Insert(name)
return true
}, AllContainers)
// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
excludedSecretPaths := sets.NewString(
excludedSecretPaths := sets.New[string](
"Spec.Volumes[*].VolumeSource.CephFS.SecretFile",
)
// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
// every path here should be represented as an example in the Pod stub above, with the secret name set to the path.
expectedSecretPaths := sets.NewString(
expectedSecretPaths := sets.New[string](
"Spec.Containers[*].EnvFrom[*].SecretRef",
"Spec.Containers[*].Env[*].ValueFrom.SecretKeyRef",
"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].SecretRef",
@ -326,20 +326,20 @@ func TestPodSecrets(t *testing.T) {
secretPaths := collectResourcePaths(t, "secret", nil, "", reflect.TypeOf(&api.Pod{}))
secretPaths = secretPaths.Difference(excludedSecretPaths)
if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
t.Logf("Missing expected secret paths:\n%s", strings.Join(missingPaths.List(), "\n"))
t.Logf("Missing expected secret paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
t.Error("Missing expected secret paths. Verify VisitPodSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
}
if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
t.Logf("Extra secret paths:\n%s", strings.Join(extraPaths.List(), "\n"))
t.Logf("Extra secret paths:\n%s", strings.Join(sets.List[string](extraPaths), "\n"))
t.Error("Extra fields with 'secret' in the name found. Verify VisitPodSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
}
if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
t.Logf("Missing expected secret names:\n%s", strings.Join(missingNames.List(), "\n"))
t.Logf("Missing expected secret names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
t.Error("Missing expected secret names. Verify the pod stub above includes these references, then verify VisitPodSecretNames() is correctly finding the missing names")
}
if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
t.Logf("Extra secret names:\n%s", strings.Join(extraNames.List(), "\n"))
t.Logf("Extra secret names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
t.Error("Extra secret names extracted. Verify VisitPodSecretNames() is correctly extracting secret names")
}
@ -360,12 +360,12 @@ func TestPodSecrets(t *testing.T) {
}
// collectResourcePaths traverses the object, computing all the struct paths that lead to fields with resourcename in the name.
func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.String {
func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.Set[string] {
resourcename = strings.ToLower(resourcename)
resourcePaths := sets.NewString()
resourcePaths := sets.New[string]()
if tp.Kind() == reflect.Pointer {
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path, name, tp.Elem()))...)
return resourcePaths
}
@ -375,7 +375,7 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
switch tp.Kind() {
case reflect.Pointer:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path, name, tp.Elem()))...)
case reflect.Struct:
// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
// it contains cycles so it's easiest to just skip it.
@ -384,14 +384,14 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
}
for i := 0; i < tp.NumField(); i++ {
field := tp.Field(i)
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type))...)
}
case reflect.Interface:
t.Errorf("cannot find %s fields in interface{} field %s", resourcename, path.String())
case reflect.Map:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()))...)
case reflect.Slice:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()))...)
default:
// all primitive types
}
@ -448,7 +448,7 @@ func TestPodConfigmaps(t *testing.T) {
Name: "Spec.Volumes[*].VolumeSource.ConfigMap"}}}}},
},
}
extractedNames := sets.NewString()
extractedNames := sets.New[string]()
VisitPodConfigmapNames(pod, func(name string) bool {
extractedNames.Insert(name)
return true
@ -456,7 +456,7 @@ func TestPodConfigmaps(t *testing.T) {
// expectedPaths holds struct paths to fields with "ConfigMap" in the name that are references to ConfigMap API objects.
// every path here should be represented as an example in the Pod stub above, with the ConfigMap name set to the path.
expectedPaths := sets.NewString(
expectedPaths := sets.New[string](
"Spec.Containers[*].EnvFrom[*].ConfigMapRef",
"Spec.Containers[*].Env[*].ValueFrom.ConfigMapKeyRef",
"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].ConfigMapRef",
@ -468,20 +468,20 @@ func TestPodConfigmaps(t *testing.T) {
)
collectPaths := collectResourcePaths(t, "ConfigMap", nil, "", reflect.TypeOf(&api.Pod{}))
if missingPaths := expectedPaths.Difference(collectPaths); len(missingPaths) > 0 {
t.Logf("Missing expected paths:\n%s", strings.Join(missingPaths.List(), "\n"))
t.Logf("Missing expected paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
t.Error("Missing expected paths. Verify VisitPodConfigmapNames() is correctly finding the missing paths, then correct expectedPaths")
}
if extraPaths := collectPaths.Difference(expectedPaths); len(extraPaths) > 0 {
t.Logf("Extra paths:\n%s", strings.Join(extraPaths.List(), "\n"))
t.Logf("Extra paths:\n%s", strings.Join(sets.List[string](extraPaths), "\n"))
t.Error("Extra fields with resource in the name found. Verify VisitPodConfigmapNames() is including these fields if appropriate, then correct expectedPaths")
}
if missingNames := expectedPaths.Difference(extractedNames); len(missingNames) > 0 {
t.Logf("Missing expected names:\n%s", strings.Join(missingNames.List(), "\n"))
t.Logf("Missing expected names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
t.Error("Missing expected names. Verify the pod stub above includes these references, then verify VisitPodConfigmapNames() is correctly finding the missing names")
}
if extraNames := extractedNames.Difference(expectedPaths); len(extraNames) > 0 {
t.Logf("Extra names:\n%s", strings.Join(extraNames.List(), "\n"))
t.Logf("Extra names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
t.Error("Extra names extracted. Verify VisitPodConfigmapNames() is correctly extracting resource names")
}

View File

@ -170,7 +170,7 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
// duplicate hostAliases (#91670, #58477)
if len(podSpec.HostAliases) > 1 {
items := sets.NewString()
items := sets.New[string]()
for i, item := range podSpec.HostAliases {
if items.Has(item.IP) {
warnings = append(warnings, fmt.Sprintf("%s: duplicate ip %q", fieldPath.Child("spec", "hostAliases").Index(i).Child("ip"), item.IP))
@ -182,7 +182,7 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
// duplicate imagePullSecrets (#91629, #58477)
if len(podSpec.ImagePullSecrets) > 1 {
items := sets.NewString()
items := sets.New[string]()
for i, item := range podSpec.ImagePullSecrets {
if items.Has(item.Name) {
warnings = append(warnings, fmt.Sprintf("%s: duplicate name %q", fieldPath.Child("spec", "imagePullSecrets").Index(i).Child("name"), item.Name))
@ -237,7 +237,7 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
// duplicate containers[*].env (#86163, #93266, #58477)
if len(c.Env) > 1 {
items := sets.NewString()
items := sets.New[string]()
for i, item := range c.Env {
if items.Has(item.Name) {
// a previous value exists, but it might be OK

View File

@ -1066,12 +1066,12 @@ func TestWarnings(t *testing.T) {
if tc.oldTemplate != nil {
oldTemplate = tc.oldTemplate
}
actual := sets.NewString(GetWarningsForPodTemplate(context.TODO(), nil, tc.template, oldTemplate)...)
expected := sets.NewString(tc.expected...)
for _, missing := range expected.Difference(actual).List() {
actual := sets.New[string](GetWarningsForPodTemplate(context.TODO(), nil, tc.template, oldTemplate)...)
expected := sets.New[string](tc.expected...)
for _, missing := range sets.List[string](expected.Difference(actual)) {
t.Errorf("missing: %s", missing)
}
for _, extra := range actual.Difference(expected).List() {
for _, extra := range sets.List[string](actual.Difference(expected)) {
t.Errorf("extra: %s", extra)
}
})
@ -1084,12 +1084,12 @@ func TestWarnings(t *testing.T) {
Spec: tc.template.Spec,
}
}
actual := sets.NewString(GetWarningsForPod(context.TODO(), pod, &api.Pod{})...)
expected := sets.NewString(tc.expected...)
for _, missing := range expected.Difference(actual).List() {
actual := sets.New[string](GetWarningsForPod(context.TODO(), pod, &api.Pod{})...)
expected := sets.New[string](tc.expected...)
for _, missing := range sets.List[string](expected.Difference(actual)) {
t.Errorf("missing: %s", missing)
}
for _, extra := range actual.Difference(expected).List() {
for _, extra := range sets.List[string](actual.Difference(expected)) {
t.Errorf("extra: %s", extra)
}
})

View File

@ -76,12 +76,12 @@ func TestStorageClassWarnings(t *testing.T) {
for _, tc := range testcases {
t.Run("podspec_"+tc.name, func(t *testing.T) {
actual := sets.NewString(GetWarningsForStorageClass(tc.template)...)
expected := sets.NewString(tc.expected...)
for _, missing := range expected.Difference(actual).List() {
actual := sets.New[string](GetWarningsForStorageClass(tc.template)...)
expected := sets.New[string](tc.expected...)
for _, missing := range sets.List[string](expected.Difference(actual)) {
t.Errorf("missing: %s", missing)
}
for _, extra := range actual.Difference(expected).List() {
for _, extra := range sets.List[string](actual.Difference(expected)) {
t.Errorf("extra: %s", extra)
}
})
@ -157,12 +157,12 @@ func TestCSIStorageCapacityWarnings(t *testing.T) {
for _, tc := range testcases {
t.Run("podspec_"+tc.name, func(t *testing.T) {
actual := sets.NewString(GetWarningsForCSIStorageCapacity(tc.template)...)
expected := sets.NewString(tc.expected...)
for _, missing := range expected.Difference(actual).List() {
actual := sets.New[string](GetWarningsForCSIStorageCapacity(tc.template)...)
expected := sets.New[string](tc.expected...)
for _, missing := range sets.List[string](expected.Difference(actual)) {
t.Errorf("missing: %s", missing)
}
for _, extra := range actual.Difference(expected).List() {
for _, extra := range sets.List[string](actual.Difference(expected)) {
t.Errorf("extra: %s", extra)
}
})

View File

@ -149,7 +149,7 @@ func TestSpecificKind(t *testing.T) {
roundtrip.RoundTripSpecificKind(t, internalGVK, legacyscheme.Scheme, legacyscheme.Codecs, fuzzer, nil)
}
var nonRoundTrippableTypes = sets.NewString(
var nonRoundTrippableTypes = sets.New[string](
"ExportOptions",
"GetOptions",
// WatchEvent does not include kind and version and can only be deserialized

View File

@ -157,8 +157,8 @@ func TestPVSecrets(t *testing.T) {
Name: "Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef",
Namespace: "csi"}}}}},
}
extractedNames := sets.NewString()
extractedNamesWithNamespace := sets.NewString()
extractedNames := sets.New[string]()
extractedNamesWithNamespace := sets.New[string]()
for _, pv := range pvs {
VisitPVSecretNames(pv, func(namespace, name string, kubeletVisible bool) bool {
@ -169,13 +169,13 @@ func TestPVSecrets(t *testing.T) {
}
// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
excludedSecretPaths := sets.NewString(
excludedSecretPaths := sets.New[string](
"Spec.PersistentVolumeSource.CephFS.SecretFile",
"Spec.PersistentVolumeSource.AzureFile.SecretNamespace",
)
// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
// every path here should be represented as an example in the PV stub above, with the secret name set to the path.
expectedSecretPaths := sets.NewString(
expectedSecretPaths := sets.New[string](
"Spec.PersistentVolumeSource.AzureFile.SecretName",
"Spec.PersistentVolumeSource.CephFS.SecretRef",
"Spec.PersistentVolumeSource.Cinder.SecretRef",
@ -193,24 +193,24 @@ func TestPVSecrets(t *testing.T) {
secretPaths := collectSecretPaths(t, nil, "", reflect.TypeOf(&api.PersistentVolume{}))
secretPaths = secretPaths.Difference(excludedSecretPaths)
if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
t.Logf("Missing expected secret paths:\n%s", strings.Join(missingPaths.List(), "\n"))
t.Logf("Missing expected secret paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
t.Error("Missing expected secret paths. Verify VisitPVSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
}
if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
t.Logf("Extra secret paths:\n%s", strings.Join(extraPaths.List(), "\n"))
t.Logf("Extra secret paths:\n%s", strings.Join(sets.List[string](extraPaths), "\n"))
t.Error("Extra fields with 'secret' in the name found. Verify VisitPVSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
}
if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
t.Logf("Missing expected secret names:\n%s", strings.Join(missingNames.List(), "\n"))
t.Logf("Missing expected secret names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
t.Error("Missing expected secret names. Verify the PV stub above includes these references, then verify VisitPVSecretNames() is correctly finding the missing names")
}
if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
t.Logf("Extra secret names:\n%s", strings.Join(extraNames.List(), "\n"))
t.Logf("Extra secret names:\n%s", strings.Join(sets.List(extraNames), "\n"))
t.Error("Extra secret names extracted. Verify VisitPVSecretNames() is correctly extracting secret names")
}
expectedNamespacedNames := sets.NewString(
expectedNamespacedNames := sets.New[string](
"claimrefns/Spec.PersistentVolumeSource.AzureFile.SecretName",
"Spec.PersistentVolumeSource.AzureFile.SecretNamespace/Spec.PersistentVolumeSource.AzureFile.SecretName",
@ -240,11 +240,11 @@ func TestPVSecrets(t *testing.T) {
"csi/Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef",
)
if missingNames := expectedNamespacedNames.Difference(extractedNamesWithNamespace); len(missingNames) > 0 {
t.Logf("Missing expected namespaced names:\n%s", strings.Join(missingNames.List(), "\n"))
t.Logf("Missing expected namespaced names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
t.Error("Missing expected namespaced names. Verify the PV stub above includes these references, then verify VisitPVSecretNames() is correctly finding the missing names")
}
if extraNames := extractedNamesWithNamespace.Difference(expectedNamespacedNames); len(extraNames) > 0 {
t.Logf("Extra namespaced names:\n%s", strings.Join(extraNames.List(), "\n"))
t.Logf("Extra namespaced names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
t.Error("Extra namespaced names extracted. Verify VisitPVSecretNames() is correctly extracting secret names")
}
@ -263,11 +263,11 @@ func TestPVSecrets(t *testing.T) {
}
// collectSecretPaths traverses the object, computing all the struct paths that lead to fields with "secret" in the name.
func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.Type) sets.String {
secretPaths := sets.NewString()
func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.Type) sets.Set[string] {
secretPaths := sets.New[string]()
if tp.Kind() == reflect.Pointer {
secretPaths.Insert(collectSecretPaths(t, path, name, tp.Elem()).List()...)
secretPaths.Insert(sets.List[string](collectSecretPaths(t, path, name, tp.Elem()))...)
return secretPaths
}
@ -277,7 +277,7 @@ func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.
switch tp.Kind() {
case reflect.Pointer:
secretPaths.Insert(collectSecretPaths(t, path, name, tp.Elem()).List()...)
secretPaths.Insert(sets.List[string](collectSecretPaths(t, path, name, tp.Elem()))...)
case reflect.Struct:
// ObjectMeta should not have any field with the word "secret" in it;
// it contains cycles so it's easiest to just skip it.
@ -286,14 +286,14 @@ func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.
}
for i := 0; i < tp.NumField(); i++ {
field := tp.Field(i)
secretPaths.Insert(collectSecretPaths(t, path.Child(field.Name), field.Name, field.Type).List()...)
secretPaths.Insert(sets.List[string](collectSecretPaths(t, path.Child(field.Name), field.Name, field.Type))...)
}
case reflect.Interface:
t.Errorf("cannot find secret fields in interface{} field %s", path.String())
case reflect.Map:
secretPaths.Insert(collectSecretPaths(t, path.Key("*"), "", tp.Elem()).List()...)
secretPaths.Insert(sets.List[string](collectSecretPaths(t, path.Key("*"), "", tp.Elem()))...)
case reflect.Slice:
secretPaths.Insert(collectSecretPaths(t, path.Key("*"), "", tp.Elem()).List()...)
secretPaths.Insert(sets.List[string](collectSecretPaths(t, path.Key("*"), "", tp.Elem()))...)
default:
// all primitive types
}

View File

@ -453,19 +453,19 @@ func TestPodSecrets(t *testing.T) {
Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.SecretKeyRef"}}}}}}}},
},
}
extractedNames := sets.NewString()
extractedNames := sets.New[string]()
VisitPodSecretNames(pod, func(name string) bool {
extractedNames.Insert(name)
return true
})
// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
excludedSecretPaths := sets.NewString(
excludedSecretPaths := sets.New[string](
"Spec.Volumes[*].VolumeSource.CephFS.SecretFile",
)
// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
// every path here should be represented as an example in the Pod stub above, with the secret name set to the path.
expectedSecretPaths := sets.NewString(
expectedSecretPaths := sets.New[string](
"Spec.Containers[*].EnvFrom[*].SecretRef",
"Spec.Containers[*].Env[*].ValueFrom.SecretKeyRef",
"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].SecretRef",
@ -489,20 +489,20 @@ func TestPodSecrets(t *testing.T) {
secretPaths := collectResourcePaths(t, "secret", nil, "", reflect.TypeOf(&v1.Pod{}))
secretPaths = secretPaths.Difference(excludedSecretPaths)
if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
t.Logf("Missing expected secret paths:\n%s", strings.Join(missingPaths.List(), "\n"))
t.Logf("Missing expected secret paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
t.Error("Missing expected secret paths. Verify VisitPodSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
}
if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
t.Logf("Extra secret paths:\n%s", strings.Join(extraPaths.List(), "\n"))
t.Logf("Extra secret paths:\n%s", strings.Join(sets.List(extraPaths), "\n"))
t.Error("Extra fields with 'secret' in the name found. Verify VisitPodSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
}
if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
t.Logf("Missing expected secret names:\n%s", strings.Join(missingNames.List(), "\n"))
t.Logf("Missing expected secret names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
t.Error("Missing expected secret names. Verify the pod stub above includes these references, then verify VisitPodSecretNames() is correctly finding the missing names")
}
if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
t.Logf("Extra secret names:\n%s", strings.Join(extraNames.List(), "\n"))
t.Logf("Extra secret names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
t.Error("Extra secret names extracted. Verify VisitPodSecretNames() is correctly extracting secret names")
}
@ -523,12 +523,12 @@ func TestPodSecrets(t *testing.T) {
}
// collectResourcePaths traverses the object, computing all the struct paths that lead to fields with resourcename in the name.
func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.String {
func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.Set[string] {
resourcename = strings.ToLower(resourcename)
resourcePaths := sets.NewString()
resourcePaths := sets.New[string]()
if tp.Kind() == reflect.Pointer {
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path, name, tp.Elem()))...)
return resourcePaths
}
@ -538,7 +538,7 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
switch tp.Kind() {
case reflect.Pointer:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path, name, tp.Elem()))...)
case reflect.Struct:
// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
// it contains cycles so it's easiest to just skip it.
@ -547,14 +547,14 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
}
for i := 0; i < tp.NumField(); i++ {
field := tp.Field(i)
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type))...)
}
case reflect.Interface:
t.Errorf("cannot find %s fields in interface{} field %s", resourcename, path.String())
case reflect.Map:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()))...)
case reflect.Slice:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()))...)
default:
// all primitive types
}
@ -611,7 +611,7 @@ func TestPodConfigmaps(t *testing.T) {
Name: "Spec.Volumes[*].VolumeSource.ConfigMap"}}}}},
},
}
extractedNames := sets.NewString()
extractedNames := sets.New[string]()
VisitPodConfigmapNames(pod, func(name string) bool {
extractedNames.Insert(name)
return true
@ -619,7 +619,7 @@ func TestPodConfigmaps(t *testing.T) {
// expectedPaths holds struct paths to fields with "ConfigMap" in the name that are references to ConfigMap API objects.
// every path here should be represented as an example in the Pod stub above, with the ConfigMap name set to the path.
expectedPaths := sets.NewString(
expectedPaths := sets.New[string](
"Spec.Containers[*].EnvFrom[*].ConfigMapRef",
"Spec.Containers[*].Env[*].ValueFrom.ConfigMapKeyRef",
"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].ConfigMapRef",
@ -631,20 +631,20 @@ func TestPodConfigmaps(t *testing.T) {
)
collectPaths := collectResourcePaths(t, "ConfigMap", nil, "", reflect.TypeOf(&v1.Pod{}))
if missingPaths := expectedPaths.Difference(collectPaths); len(missingPaths) > 0 {
t.Logf("Missing expected paths:\n%s", strings.Join(missingPaths.List(), "\n"))
t.Logf("Missing expected paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
t.Error("Missing expected paths. Verify VisitPodConfigmapNames() is correctly finding the missing paths, then correct expectedPaths")
}
if extraPaths := collectPaths.Difference(expectedPaths); len(extraPaths) > 0 {
t.Logf("Extra paths:\n%s", strings.Join(extraPaths.List(), "\n"))
t.Logf("Extra paths:\n%s", strings.Join(sets.List[string](extraPaths), "\n"))
t.Error("Extra fields with resource in the name found. Verify VisitPodConfigmapNames() is including these fields if appropriate, then correct expectedPaths")
}
if missingNames := expectedPaths.Difference(extractedNames); len(missingNames) > 0 {
t.Logf("Missing expected names:\n%s", strings.Join(missingNames.List(), "\n"))
t.Logf("Missing expected names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
t.Error("Missing expected names. Verify the pod stub above includes these references, then verify VisitPodConfigmapNames() is correctly finding the missing names")
}
if extraNames := extractedNames.Difference(expectedPaths); len(extraNames) > 0 {
t.Logf("Extra names:\n%s", strings.Join(extraNames.List(), "\n"))
t.Logf("Extra names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
t.Error("Extra names extracted. Verify VisitPodConfigmapNames() is correctly extracting resource names")
}