From 1c1a53772766b67ee9787d13ecb7c8beb487e67e Mon Sep 17 00:00:00 2001 From: Andrii Korotkov Date: Sun, 20 Jul 2025 17:01:39 -0700 Subject: [PATCH 1/2] chore: Cleanup IterateHierarchy v1 Part of https://github.com/argoproj/argo-cd/issues/23854 Remove the unused code in gitops-engine. Signed-off-by: Andrii Korotkov --- pkg/cache/cluster.go | 44 ------ pkg/cache/cluster_test.go | 228 -------------------------------- pkg/cache/mocks/ClusterCache.go | 5 - pkg/cache/predicates_test.go | 2 +- pkg/cache/resource.go | 24 ---- 5 files changed, 1 insertion(+), 302 deletions(-) diff --git a/pkg/cache/cluster.go b/pkg/cache/cluster.go index bc86e8b98..38f1e6016 100644 --- a/pkg/cache/cluster.go +++ b/pkg/cache/cluster.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "runtime/debug" - "sort" "strings" "sync" "time" @@ -130,9 +129,6 @@ type ClusterCache interface { Invalidate(opts ...UpdateSettingsFunc) // FindResources returns resources that matches given list of predicates from specified namespace or everywhere if specified namespace is empty FindResources(namespace string, predicates ...func(r *Resource) bool) map[kube.ResourceKey]*Resource - // IterateHierarchy iterates resource tree starting from the specified top level resource and executes callback for each resource in the tree. - // The action callback returns true if iteration should continue and false otherwise. - IterateHierarchy(key kube.ResourceKey, action func(resource *Resource, namespaceResources map[kube.ResourceKey]*Resource) bool) // IterateHierarchyV2 iterates resource tree starting from the specified top level resources and executes callback for each resource in the tree. // The action callback returns true if iteration should continue and false otherwise. IterateHierarchyV2(keys []kube.ResourceKey, action func(resource *Resource, namespaceResources map[kube.ResourceKey]*Resource) bool) @@ -1055,46 +1051,6 @@ func (c *clusterCache) FindResources(namespace string, predicates ...func(r *Res return result } -// IterateHierarchy iterates resource tree starting from the specified top level resource and executes callback for each resource in the tree -func (c *clusterCache) IterateHierarchy(key kube.ResourceKey, action func(resource *Resource, namespaceResources map[kube.ResourceKey]*Resource) bool) { - c.lock.RLock() - defer c.lock.RUnlock() - if res, ok := c.resources[key]; ok { - nsNodes := c.nsIndex[key.Namespace] - if !action(res, nsNodes) { - return - } - childrenByUID := make(map[types.UID][]*Resource) - for _, child := range nsNodes { - if res.isParentOf(child) { - childrenByUID[child.Ref.UID] = append(childrenByUID[child.Ref.UID], child) - } - } - // make sure children has no duplicates - for _, children := range childrenByUID { - if len(children) > 0 { - // The object might have multiple children with the same UID (e.g. replicaset from apps and extensions group). It is ok to pick any object but we need to make sure - // we pick the same child after every refresh. - sort.Slice(children, func(i, j int) bool { - key1 := children[i].ResourceKey() - key2 := children[j].ResourceKey() - return strings.Compare(key1.String(), key2.String()) < 0 - }) - child := children[0] - if action(child, nsNodes) { - child.iterateChildren(nsNodes, map[kube.ResourceKey]bool{res.ResourceKey(): true}, func(err error, child *Resource, namespaceResources map[kube.ResourceKey]*Resource) bool { - if err != nil { - c.log.V(2).Info(err.Error()) - return false - } - return action(child, namespaceResources) - }) - } - } - } - } -} - // IterateHierarchy iterates resource tree starting from the specified top level resources and executes callback for each resource in the tree func (c *clusterCache) IterateHierarchyV2(keys []kube.ResourceKey, action func(resource *Resource, namespaceResources map[kube.ResourceKey]*Resource) bool) { c.lock.RLock() diff --git a/pkg/cache/cluster_test.go b/pkg/cache/cluster_test.go index 8aa286fc4..df978a742 100644 --- a/pkg/cache/cluster_test.go +++ b/pkg/cache/cluster_test.go @@ -4,8 +4,6 @@ import ( "context" "errors" "fmt" - "sort" - "strings" "sync" "testing" "time" @@ -138,15 +136,6 @@ func (c *clusterCache) WithAPIResources(newApiResources []kube.APIResourceInfo) return c } -func getChildren(cluster *clusterCache, un *unstructured.Unstructured) []*Resource { - hierarchy := make([]*Resource, 0) - cluster.IterateHierarchy(kube.GetResourceKey(un), func(child *Resource, _ map[kube.ResourceKey]*Resource) bool { - hierarchy = append(hierarchy, child) - return true - }) - return hierarchy[1:] -} - // Benchmark_sync is meant to simulate cluster initialization when populateResourceInfoHandler does nontrivial work. func Benchmark_sync(t *testing.B) { resources := []runtime.Object{} @@ -350,49 +339,6 @@ func TestEnsureSyncedSingleNamespace(t *testing.T) { assert.ElementsMatch(t, []string{"helm-guestbook1"}, names) } -func TestGetChildren(t *testing.T) { - cluster := newCluster(t, testPod1(), testRS(), testDeploy()) - err := cluster.EnsureSynced() - require.NoError(t, err) - - rsChildren := getChildren(cluster, mustToUnstructured(testRS())) - assert.Equal(t, []*Resource{{ - Ref: corev1.ObjectReference{ - Kind: "Pod", - Namespace: "default", - Name: "helm-guestbook-pod-1", - APIVersion: "v1", - UID: "1", - }, - OwnerRefs: []metav1.OwnerReference{{ - APIVersion: "apps/v1", - Kind: "ReplicaSet", - Name: "helm-guestbook-rs", - UID: "2", - }}, - ResourceVersion: "123", - CreationTimestamp: &metav1.Time{ - Time: testCreationTime.Local(), - }, - }}, rsChildren) - deployChildren := getChildren(cluster, mustToUnstructured(testDeploy())) - - assert.Equal(t, append([]*Resource{{ - Ref: corev1.ObjectReference{ - Kind: "ReplicaSet", - Namespace: "default", - Name: "helm-guestbook-rs", - APIVersion: "apps/v1", - UID: "2", - }, - ResourceVersion: "123", - OwnerRefs: []metav1.OwnerReference{{APIVersion: "apps/v1beta1", Kind: "Deployment", Name: "helm-guestbook", UID: "3"}}, - CreationTimestamp: &metav1.Time{ - Time: testCreationTime.Local(), - }, - }}, rsChildren...), deployChildren) -} - func TestGetManagedLiveObjs(t *testing.T) { cluster := newCluster(t, testPod1(), testRS(), testDeploy()) cluster.Invalidate(SetPopulateResourceInfoHandler(func(_ *unstructured.Unstructured, _ bool) (info any, cacheManifest bool) { @@ -648,77 +594,6 @@ metadata: } } -func TestChildDeletedEvent(t *testing.T) { - cluster := newCluster(t, testPod1(), testRS(), testDeploy()) - err := cluster.EnsureSynced() - require.NoError(t, err) - - cluster.recordEvent(watch.Deleted, mustToUnstructured(testPod1())) - - rsChildren := getChildren(cluster, mustToUnstructured(testRS())) - assert.Equal(t, []*Resource{}, rsChildren) -} - -func TestProcessNewChildEvent(t *testing.T) { - cluster := newCluster(t, testPod1(), testRS(), testDeploy()) - err := cluster.EnsureSynced() - require.NoError(t, err) - newPod := strToUnstructured(` - apiVersion: v1 - kind: Pod - metadata: - uid: "5" - name: helm-guestbook-pod-1-new - namespace: default - ownerReferences: - - apiVersion: apps/v1 - kind: ReplicaSet - name: helm-guestbook-rs - uid: "2" - resourceVersion: "123"`) - - cluster.recordEvent(watch.Added, newPod) - - rsChildren := getChildren(cluster, mustToUnstructured(testRS())) - sort.Slice(rsChildren, func(i, j int) bool { - return strings.Compare(rsChildren[i].Ref.Name, rsChildren[j].Ref.Name) < 0 - }) - assert.Equal(t, []*Resource{{ - Ref: corev1.ObjectReference{ - Kind: "Pod", - Namespace: "default", - Name: "helm-guestbook-pod-1", - APIVersion: "v1", - UID: "1", - }, - OwnerRefs: []metav1.OwnerReference{{ - APIVersion: "apps/v1", - Kind: "ReplicaSet", - Name: "helm-guestbook-rs", - UID: "2", - }}, - ResourceVersion: "123", - CreationTimestamp: &metav1.Time{ - Time: testCreationTime.Local(), - }, - }, { - Ref: corev1.ObjectReference{ - Kind: "Pod", - Namespace: "default", - Name: "helm-guestbook-pod-1-new", - APIVersion: "v1", - UID: "5", - }, - OwnerRefs: []metav1.OwnerReference{{ - APIVersion: "apps/v1", - Kind: "ReplicaSet", - Name: "helm-guestbook-rs", - UID: "2", - }}, - ResourceVersion: "123", - }}, rsChildren) -} - func TestWatchCacheUpdated(t *testing.T) { removed := testPod1() removed.SetName(removed.GetName() + "-removed-pod") @@ -770,23 +645,6 @@ func TestNamespaceModeReplace(t *testing.T) { assert.True(t, ok) } -func TestGetDuplicatedChildren(t *testing.T) { - extensionsRS := testExtensionsRS() - cluster := newCluster(t, testDeploy(), testRS(), extensionsRS) - err := cluster.EnsureSynced() - - require.NoError(t, err) - - // Get children multiple times to make sure the right child is picked up every time. - for i := 0; i < 5; i++ { - children := getChildren(cluster, mustToUnstructured(testDeploy())) - assert.Len(t, children, 1) - assert.Equal(t, "apps/v1", children[0].Ref.APIVersion) - assert.Equal(t, kube.ReplicaSetKind, children[0].Ref.Kind) - assert.Equal(t, testRS().GetName(), children[0].Ref.Name) - } -} - func TestGetClusterInfo(t *testing.T) { cluster := newCluster(t) cluster.apiResources = []kube.APIResourceInfo{{GroupKind: schema.GroupKind{Group: "test", Kind: "test kind"}}} @@ -1045,92 +903,6 @@ func testDeploy() *appsv1.Deployment { } } -func TestIterateHierachy(t *testing.T) { - cluster := newCluster(t, testPod1(), testPod2(), testRS(), testExtensionsRS(), testDeploy()) - err := cluster.EnsureSynced() - require.NoError(t, err) - - t.Run("IterateAll", func(t *testing.T) { - keys := []kube.ResourceKey{} - cluster.IterateHierarchy(kube.GetResourceKey(mustToUnstructured(testDeploy())), func(child *Resource, _ map[kube.ResourceKey]*Resource) bool { - keys = append(keys, child.ResourceKey()) - return true - }) - - assert.ElementsMatch(t, - []kube.ResourceKey{ - kube.GetResourceKey(mustToUnstructured(testPod1())), - kube.GetResourceKey(mustToUnstructured(testPod2())), - kube.GetResourceKey(mustToUnstructured(testRS())), - kube.GetResourceKey(mustToUnstructured(testDeploy())), - }, - keys) - }) - - t.Run("ExitAtRoot", func(t *testing.T) { - keys := []kube.ResourceKey{} - cluster.IterateHierarchy(kube.GetResourceKey(mustToUnstructured(testDeploy())), func(child *Resource, _ map[kube.ResourceKey]*Resource) bool { - keys = append(keys, child.ResourceKey()) - return false - }) - - assert.ElementsMatch(t, - []kube.ResourceKey{ - kube.GetResourceKey(mustToUnstructured(testDeploy())), - }, - keys) - }) - - t.Run("ExitAtSecondLevelChild", func(t *testing.T) { - keys := []kube.ResourceKey{} - cluster.IterateHierarchy(kube.GetResourceKey(mustToUnstructured(testDeploy())), func(child *Resource, _ map[kube.ResourceKey]*Resource) bool { - keys = append(keys, child.ResourceKey()) - return child.ResourceKey().Kind != kube.ReplicaSetKind - }) - - assert.ElementsMatch(t, - []kube.ResourceKey{ - kube.GetResourceKey(mustToUnstructured(testDeploy())), - kube.GetResourceKey(mustToUnstructured(testRS())), - }, - keys) - }) - - t.Run("ExitAtThirdLevelChild", func(t *testing.T) { - keys := []kube.ResourceKey{} - cluster.IterateHierarchy(kube.GetResourceKey(mustToUnstructured(testDeploy())), func(child *Resource, _ map[kube.ResourceKey]*Resource) bool { - keys = append(keys, child.ResourceKey()) - return child.ResourceKey().Kind != kube.PodKind - }) - - assert.ElementsMatch(t, - []kube.ResourceKey{ - kube.GetResourceKey(mustToUnstructured(testDeploy())), - kube.GetResourceKey(mustToUnstructured(testRS())), - kube.GetResourceKey(mustToUnstructured(testPod1())), - kube.GetResourceKey(mustToUnstructured(testPod2())), - }, - keys) - }) - - // After uid is backfilled for owner of pod2, it should appear in results here as well. - t.Run("IterateStartFromExtensionsRS", func(t *testing.T) { - keys := []kube.ResourceKey{} - cluster.IterateHierarchy(kube.GetResourceKey(mustToUnstructured(testExtensionsRS())), func(child *Resource, _ map[kube.ResourceKey]*Resource) bool { - keys = append(keys, child.ResourceKey()) - return true - }) - - assert.ElementsMatch(t, - []kube.ResourceKey{ - kube.GetResourceKey(mustToUnstructured(testPod1())), - kube.GetResourceKey(mustToUnstructured(testPod2())), - kube.GetResourceKey(mustToUnstructured(testExtensionsRS())), - }, - keys) - }) -} - func TestIterateHierachyV2(t *testing.T) { cluster := newCluster(t, testPod1(), testPod2(), testRS(), testExtensionsRS(), testDeploy()) err := cluster.EnsureSynced() diff --git a/pkg/cache/mocks/ClusterCache.go b/pkg/cache/mocks/ClusterCache.go index a4afa3119..b0179f85a 100644 --- a/pkg/cache/mocks/ClusterCache.go +++ b/pkg/cache/mocks/ClusterCache.go @@ -232,11 +232,6 @@ func (_m *ClusterCache) IsNamespaced(gk schema.GroupKind) (bool, error) { return r0, r1 } -// IterateHierarchy provides a mock function with given fields: key, action -func (_m *ClusterCache) IterateHierarchy(key kube.ResourceKey, action func(*cache.Resource, map[kube.ResourceKey]*cache.Resource) bool) { - _m.Called(key, action) -} - // IterateHierarchyV2 provides a mock function with given fields: keys, action func (_m *ClusterCache) IterateHierarchyV2(keys []kube.ResourceKey, action func(*cache.Resource, map[kube.ResourceKey]*cache.Resource) bool) { _m.Called(keys, action) diff --git a/pkg/cache/predicates_test.go b/pkg/cache/predicates_test.go index 73936c85c..74522f71e 100644 --- a/pkg/cache/predicates_test.go +++ b/pkg/cache/predicates_test.go @@ -115,7 +115,7 @@ func ExampleNewClusterCache_inspectNamespaceResources() { } // Iterate default namespace resources tree for _, root := range clusterCache.FindResources("default", TopLevelResource) { - clusterCache.IterateHierarchy(root.ResourceKey(), func(resource *Resource, _ map[kube.ResourceKey]*Resource) bool { + clusterCache.IterateHierarchyV2([]kube.ResourceKey{root.ResourceKey()}, func(resource *Resource, _ map[kube.ResourceKey]*Resource) bool { fmt.Printf("resource: %s, info: %v\n", resource.Ref.String(), resource.Info) return true }) diff --git a/pkg/cache/resource.go b/pkg/cache/resource.go index c46fa85fb..8a7202950 100644 --- a/pkg/cache/resource.go +++ b/pkg/cache/resource.go @@ -75,30 +75,6 @@ func (r *Resource) toOwnerRef() metav1.OwnerReference { return metav1.OwnerReference{UID: r.Ref.UID, Name: r.Ref.Name, Kind: r.Ref.Kind, APIVersion: r.Ref.APIVersion} } -func newResourceKeySet(set map[kube.ResourceKey]bool, keys ...kube.ResourceKey) map[kube.ResourceKey]bool { - newSet := make(map[kube.ResourceKey]bool) - for k, v := range set { - newSet[k] = v - } - for i := range keys { - newSet[keys[i]] = true - } - return newSet -} - -func (r *Resource) iterateChildren(ns map[kube.ResourceKey]*Resource, parents map[kube.ResourceKey]bool, action func(err error, child *Resource, namespaceResources map[kube.ResourceKey]*Resource) bool) { - for childKey, child := range ns { - if r.isParentOf(ns[childKey]) { - if parents[childKey] { - key := r.ResourceKey() - _ = action(fmt.Errorf("circular dependency detected. %s is child and parent of %s", childKey.String(), key.String()), child, ns) - } else if action(nil, child, ns) { - child.iterateChildren(ns, newResourceKeySet(parents, r.ResourceKey()), action) - } - } - } -} - // iterateChildrenV2 is a depth-first traversal of the graph of resources starting from the current resource. func (r *Resource) iterateChildrenV2(graph map[kube.ResourceKey]map[types.UID]*Resource, ns map[kube.ResourceKey]*Resource, visited map[kube.ResourceKey]int, action func(err error, child *Resource, namespaceResources map[kube.ResourceKey]*Resource) bool) { key := r.ResourceKey() From b73d2f51177bc422953bb0fcd9f4384e625f3fe7 Mon Sep 17 00:00:00 2001 From: Andrii Korotkov Date: Sun, 20 Jul 2025 17:14:23 -0700 Subject: [PATCH 2/2] Revert some deleted tests Signed-off-by: Andrii Korotkov --- pkg/cache/cluster_test.go | 157 ++++++++++++++++++++++++++++++++++---- 1 file changed, 142 insertions(+), 15 deletions(-) diff --git a/pkg/cache/cluster_test.go b/pkg/cache/cluster_test.go index df978a742..7bac78043 100644 --- a/pkg/cache/cluster_test.go +++ b/pkg/cache/cluster_test.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "sort" + "strings" "sync" "testing" "time" @@ -136,6 +138,15 @@ func (c *clusterCache) WithAPIResources(newApiResources []kube.APIResourceInfo) return c } +func getChildren(cluster *clusterCache, un *unstructured.Unstructured) []*Resource { + hierarchy := make([]*Resource, 0) + cluster.IterateHierarchyV2([]kube.ResourceKey{kube.GetResourceKey(un)}, func(child *Resource, _ map[kube.ResourceKey]*Resource) bool { + hierarchy = append(hierarchy, child) + return true + }) + return hierarchy[1:] +} + // Benchmark_sync is meant to simulate cluster initialization when populateResourceInfoHandler does nontrivial work. func Benchmark_sync(t *testing.B) { resources := []runtime.Object{} @@ -339,6 +350,49 @@ func TestEnsureSyncedSingleNamespace(t *testing.T) { assert.ElementsMatch(t, []string{"helm-guestbook1"}, names) } +func TestGetChildren(t *testing.T) { + cluster := newCluster(t, testPod1(), testRS(), testDeploy()) + err := cluster.EnsureSynced() + require.NoError(t, err) + + rsChildren := getChildren(cluster, mustToUnstructured(testRS())) + assert.Equal(t, []*Resource{{ + Ref: corev1.ObjectReference{ + Kind: "Pod", + Namespace: "default", + Name: "helm-guestbook-pod-1", + APIVersion: "v1", + UID: "1", + }, + OwnerRefs: []metav1.OwnerReference{{ + APIVersion: "apps/v1", + Kind: "ReplicaSet", + Name: "helm-guestbook-rs", + UID: "2", + }}, + ResourceVersion: "123", + CreationTimestamp: &metav1.Time{ + Time: testCreationTime.Local(), + }, + }}, rsChildren) + deployChildren := getChildren(cluster, mustToUnstructured(testDeploy())) + + assert.Equal(t, append([]*Resource{{ + Ref: corev1.ObjectReference{ + Kind: "ReplicaSet", + Namespace: "default", + Name: "helm-guestbook-rs", + APIVersion: "apps/v1", + UID: "2", + }, + ResourceVersion: "123", + OwnerRefs: []metav1.OwnerReference{{APIVersion: "apps/v1beta1", Kind: "Deployment", Name: "helm-guestbook", UID: "3"}}, + CreationTimestamp: &metav1.Time{ + Time: testCreationTime.Local(), + }, + }}, rsChildren...), deployChildren) +} + func TestGetManagedLiveObjs(t *testing.T) { cluster := newCluster(t, testPod1(), testRS(), testDeploy()) cluster.Invalidate(SetPopulateResourceInfoHandler(func(_ *unstructured.Unstructured, _ bool) (info any, cacheManifest bool) { @@ -594,6 +648,77 @@ metadata: } } +func TestChildDeletedEvent(t *testing.T) { + cluster := newCluster(t, testPod1(), testRS(), testDeploy()) + err := cluster.EnsureSynced() + require.NoError(t, err) + + cluster.recordEvent(watch.Deleted, mustToUnstructured(testPod1())) + + rsChildren := getChildren(cluster, mustToUnstructured(testRS())) + assert.Equal(t, []*Resource{}, rsChildren) +} + +func TestProcessNewChildEvent(t *testing.T) { + cluster := newCluster(t, testPod1(), testRS(), testDeploy()) + err := cluster.EnsureSynced() + require.NoError(t, err) + newPod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + uid: "5" + name: helm-guestbook-pod-1-new + namespace: default + ownerReferences: + - apiVersion: apps/v1 + kind: ReplicaSet + name: helm-guestbook-rs + uid: "2" + resourceVersion: "123"`) + + cluster.recordEvent(watch.Added, newPod) + + rsChildren := getChildren(cluster, mustToUnstructured(testRS())) + sort.Slice(rsChildren, func(i, j int) bool { + return strings.Compare(rsChildren[i].Ref.Name, rsChildren[j].Ref.Name) < 0 + }) + assert.Equal(t, []*Resource{{ + Ref: corev1.ObjectReference{ + Kind: "Pod", + Namespace: "default", + Name: "helm-guestbook-pod-1", + APIVersion: "v1", + UID: "1", + }, + OwnerRefs: []metav1.OwnerReference{{ + APIVersion: "apps/v1", + Kind: "ReplicaSet", + Name: "helm-guestbook-rs", + UID: "2", + }}, + ResourceVersion: "123", + CreationTimestamp: &metav1.Time{ + Time: testCreationTime.Local(), + }, + }, { + Ref: corev1.ObjectReference{ + Kind: "Pod", + Namespace: "default", + Name: "helm-guestbook-pod-1-new", + APIVersion: "v1", + UID: "5", + }, + OwnerRefs: []metav1.OwnerReference{{ + APIVersion: "apps/v1", + Kind: "ReplicaSet", + Name: "helm-guestbook-rs", + UID: "2", + }}, + ResourceVersion: "123", + }}, rsChildren) +} + func TestWatchCacheUpdated(t *testing.T) { removed := testPod1() removed.SetName(removed.GetName() + "-removed-pod") @@ -645,6 +770,23 @@ func TestNamespaceModeReplace(t *testing.T) { assert.True(t, ok) } +func TestGetDuplicatedChildren(t *testing.T) { + extensionsRS := testExtensionsRS() + cluster := newCluster(t, testDeploy(), testRS(), extensionsRS) + err := cluster.EnsureSynced() + + require.NoError(t, err) + + // Get children multiple times to make sure the right child is picked up every time. + for i := 0; i < 5; i++ { + children := getChildren(cluster, mustToUnstructured(testDeploy())) + assert.Len(t, children, 1) + assert.Equal(t, "apps/v1", children[0].Ref.APIVersion) + assert.Equal(t, kube.ReplicaSetKind, children[0].Ref.Kind) + assert.Equal(t, testRS().GetName(), children[0].Ref.Name) + } +} + func TestGetClusterInfo(t *testing.T) { cluster := newCluster(t) cluster.apiResources = []kube.APIResourceInfo{{GroupKind: schema.GroupKind{Group: "test", Kind: "test kind"}}} @@ -1150,18 +1292,3 @@ func BenchmarkIterateHierarchyV2(b *testing.B) { }) } } - -// func BenchmarkIterateHierarchy(b *testing.B) { -// cluster := newCluster(b) -// for _, resource := range testResources { -// cluster.setNode(resource) -// } -// b.ResetTimer() -// for n := 0; n < b.N; n++ { -// cluster.IterateHierarchy(kube.ResourceKey{ -// Namespace: "default", Name: "test-1", Kind: "Pod", -// }, func(child *Resource, _ map[kube.ResourceKey]*Resource) bool { -// return true -// }) -// } -//}