diff --git a/pkg/kubelet/apis/config/helpers_test.go b/pkg/kubelet/apis/config/helpers_test.go index 85bcaaed388..1adb0724f2e 100644 --- a/pkg/kubelet/apis/config/helpers_test.go +++ b/pkg/kubelet/apis/config/helpers_test.go @@ -35,7 +35,7 @@ func TestKubeletConfigurationPathFields(t *testing.T) { // ensure that kubeletConfigurationPathFields U kubeletConfigurationNonPathFields == allPrimitiveFieldPaths(KubeletConfiguration) expect := sets.NewString().Union(kubeletConfigurationPathFieldPaths).Union(kubeletConfigurationNonPathFieldPaths) - result := allPrimitiveFieldPaths(t, reflect.TypeOf(&KubeletConfiguration{}), nil) + result := allPrimitiveFieldPaths(t, expect, reflect.TypeOf(&KubeletConfiguration{}), nil) if !expect.Equal(result) { // expected fields missing from result missing := expect.Difference(result) @@ -58,18 +58,26 @@ func TestKubeletConfigurationPathFields(t *testing.T) { } } -func allPrimitiveFieldPaths(t *testing.T, tp reflect.Type, path *field.Path) sets.String { +// allPrimitiveFieldPaths returns the set of field paths in type `tp`, rooted at `path`. +// It recursively descends into the definition of type `tp` accumulating paths to primitive leaf fields or paths in `skipRecurseList`. +func allPrimitiveFieldPaths(t *testing.T, skipRecurseList sets.String, tp reflect.Type, path *field.Path) sets.String { + // if the current field path is in the list of paths we should not recurse into, + // return here rather than descending and accumulating child field paths + if pathStr := path.String(); len(pathStr) > 0 && skipRecurseList.Has(pathStr) { + return sets.NewString(pathStr) + } + paths := sets.NewString() switch tp.Kind() { case reflect.Ptr: - paths.Insert(allPrimitiveFieldPaths(t, tp.Elem(), path).List()...) + paths.Insert(allPrimitiveFieldPaths(t, skipRecurseList, tp.Elem(), path).List()...) case reflect.Struct: for i := 0; i < tp.NumField(); i++ { field := tp.Field(i) - paths.Insert(allPrimitiveFieldPaths(t, field.Type, path.Child(field.Name)).List()...) + paths.Insert(allPrimitiveFieldPaths(t, skipRecurseList, field.Type, path.Child(field.Name)).List()...) } case reflect.Map, reflect.Slice: - paths.Insert(allPrimitiveFieldPaths(t, tp.Elem(), path.Key("*")).List()...) + paths.Insert(allPrimitiveFieldPaths(t, skipRecurseList, tp.Elem(), path.Key("*")).List()...) case reflect.Interface: t.Fatalf("unexpected interface{} field %s", path.String()) default: @@ -97,6 +105,13 @@ type bar struct { bars []foo barMap map[string]foo + + skipRecurseStruct foo + skipRecursePointer *foo + skipRecurseList1 []foo + skipRecurseList2 []foo + skipRecurseMap1 map[string]foo + skipRecurseMap2 map[string]foo } func TestAllPrimitiveFieldPaths(t *testing.T) { @@ -109,8 +124,14 @@ func TestAllPrimitiveFieldPaths(t *testing.T) { "fooptr.foo", "bars[*].foo", "barMap[*].foo", + "skipRecurseStruct", // skip recursing a struct + "skipRecursePointer", // skip recursing a struct pointer + "skipRecurseList1", // skip recursing a list + "skipRecurseList2[*]", // skip recursing list items + "skipRecurseMap1", // skip recursing a map + "skipRecurseMap2[*]", // skip recursing map items ) - result := allPrimitiveFieldPaths(t, reflect.TypeOf(&bar{}), nil) + result := allPrimitiveFieldPaths(t, expect, reflect.TypeOf(&bar{}), nil) if !expect.Equal(result) { // expected fields missing from result missing := expect.Difference(result) @@ -233,14 +254,7 @@ var ( "ReadOnlyPort", "RegistryBurst", "RegistryPullQPS", - "ReservedMemory[*].Limits[*].Format", - "ReservedMemory[*].Limits[*].d.Dec.scale", - "ReservedMemory[*].Limits[*].d.Dec.unscaled.abs[*]", - "ReservedMemory[*].Limits[*].d.Dec.unscaled.neg", - "ReservedMemory[*].Limits[*].i.scale", - "ReservedMemory[*].Limits[*].i.value", - "ReservedMemory[*].Limits[*].s", - "ReservedMemory[*].NumaNode", + "ReservedMemory", "ReservedSystemCPUs", "RuntimeRequestTimeout.Duration", "RunOnce",