mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +00:00 
			
		
		
		
	Adds unit tests covering the problematic scenarios identified
around conflicting data in child owner references
                      Before   After
package level         51%      68%
garbagecollector.go   60%      75%
graph_builder.go      50%      81%
graph.go              50%      68%
Added/improved coverage of key functions that had lacking unit test coverage:
* attemptToDeleteWorker
* attemptToDeleteItem
* processGraphChanges (added coverage of all added code)
		
	
		
			
				
	
	
		
			213 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2020 The Kubernetes Authors.
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
package garbagecollector
 | 
						|
 | 
						|
import (
 | 
						|
	"reflect"
 | 
						|
	"testing"
 | 
						|
)
 | 
						|
 | 
						|
func TestGetAlternateOwnerIdentity(t *testing.T) {
 | 
						|
	ns1child1 := makeID("v1", "Child", "ns1", "child1", "childuid11")
 | 
						|
	ns1child2 := makeID("v1", "Child", "ns1", "child2", "childuid12")
 | 
						|
 | 
						|
	ns2child1 := makeID("v1", "Child", "ns2", "child1", "childuid21")
 | 
						|
 | 
						|
	clusterchild1 := makeID("v1", "Child", "", "child1", "childuidc1")
 | 
						|
 | 
						|
	var (
 | 
						|
		nsabsentparentns1 = makeID("v1", "NSParent", "ns1", "parentname", "parentuid")
 | 
						|
		nsabsentparentns2 = makeID("v1", "NSParent", "ns2", "parentname", "parentuid")
 | 
						|
 | 
						|
		nsabsentparent_version = makeID("xx", "NSParent", "ns1", "parentname", "parentuid")
 | 
						|
		nsabsentparent_kind    = makeID("v1", "xxxxxxxx", "ns1", "parentname", "parentuid")
 | 
						|
		nsabsentparent_name    = makeID("v1", "NSParent", "ns1", "xxxxxxxxxx", "parentuid")
 | 
						|
 | 
						|
		clusterabsentparent         = makeID("v1", "ClusterParent", "", "parentname", "parentuid")
 | 
						|
		clusterabsentparent_version = makeID("xx", "ClusterParent", "", "parentname", "parentuid")
 | 
						|
		clusterabsentparent_kind    = makeID("v1", "xxxxxxxxxxxxx", "", "parentname", "parentuid")
 | 
						|
		clusterabsentparent_name    = makeID("v1", "ClusterParent", "", "xxxxxxxxxx", "parentuid")
 | 
						|
 | 
						|
		clusterabsentparent_ns1_version = makeID("xx", "ClusterParent", "ns1", "parentname", "parentuid")
 | 
						|
		clusterabsentparent_ns1_kind    = makeID("v1", "xxxxxxxxxxxxx", "ns1", "parentname", "parentuid")
 | 
						|
	)
 | 
						|
 | 
						|
	orderedNamespacedReferences := []objectReference{
 | 
						|
		makeID("v1", "kind", "ns1", "name", "uid"),
 | 
						|
		makeID("v2", "kind", "ns1", "name", "uid"),
 | 
						|
		makeID("v3", "kind", "ns1", "name", "uid"),
 | 
						|
		makeID("v4", "kind", "ns1", "name", "uid"),
 | 
						|
		makeID("v5", "kind", "ns1", "name", "uid"),
 | 
						|
	}
 | 
						|
	orderedClusterReferences := []objectReference{
 | 
						|
		makeID("v1", "kind", "", "name", "uid"),
 | 
						|
		makeID("v2", "kind", "", "name", "uid"),
 | 
						|
		makeID("v3", "kind", "", "name", "uid"),
 | 
						|
		makeID("v4", "kind", "", "name", "uid"),
 | 
						|
		makeID("v5", "kind", "", "name", "uid"),
 | 
						|
	}
 | 
						|
 | 
						|
	testcases := []struct {
 | 
						|
		name              string
 | 
						|
		deps              []*node
 | 
						|
		verifiedAbsent    objectReference
 | 
						|
		expectedAlternate *objectReference
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name: "namespaced alternate version",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(nsabsentparentns1)),
 | 
						|
				makeNode(ns1child2, withOwners(nsabsentparent_version)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    nsabsentparentns1,
 | 
						|
			expectedAlternate: &nsabsentparent_version, // switch to alternate version
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "namespaced alternate kind",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(nsabsentparentns1)),
 | 
						|
				makeNode(ns1child2, withOwners(nsabsentparent_kind)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    nsabsentparentns1,
 | 
						|
			expectedAlternate: &nsabsentparent_kind, // switch to alternate kind
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "namespaced alternate namespace",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(nsabsentparentns1)),
 | 
						|
				makeNode(ns2child1, withOwners(nsabsentparentns2)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    nsabsentparentns1,
 | 
						|
			expectedAlternate: &nsabsentparentns2, // switch to alternate namespace
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "namespaced alternate name",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(nsabsentparentns1)),
 | 
						|
				makeNode(ns1child1, withOwners(nsabsentparent_name)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    nsabsentparentns1,
 | 
						|
			expectedAlternate: &nsabsentparent_name, // switch to alternate name
 | 
						|
		},
 | 
						|
 | 
						|
		{
 | 
						|
			name: "cluster alternate version",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(clusterabsentparent)),
 | 
						|
				makeNode(ns1child2, withOwners(clusterabsentparent_version)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    clusterabsentparent,
 | 
						|
			expectedAlternate: &clusterabsentparent_ns1_version, // switch to alternate version, namespaced to new dependent since we don't know the version is cluster-scoped
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "cluster alternate kind",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(clusterabsentparent)),
 | 
						|
				makeNode(ns1child2, withOwners(clusterabsentparent_kind)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    clusterabsentparent,
 | 
						|
			expectedAlternate: &clusterabsentparent_ns1_kind, // switch to alternate kind, namespaced to new dependent since we don't know the new kind is cluster-scoped
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "cluster alternate namespace",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(clusterabsentparent)),
 | 
						|
				makeNode(ns2child1, withOwners(clusterabsentparent)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    clusterabsentparent,
 | 
						|
			expectedAlternate: nil, // apiVersion/kind verified cluster-scoped, namespace delta ignored, no alternates found
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "cluster alternate name",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(clusterabsentparent)),
 | 
						|
				makeNode(ns1child1, withOwners(clusterabsentparent_name)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    clusterabsentparent,
 | 
						|
			expectedAlternate: &clusterabsentparent_name, // switch to alternate name, apiVersion/kind verified cluster-scoped, namespace dropped
 | 
						|
		},
 | 
						|
 | 
						|
		{
 | 
						|
			name: "namespaced ref from namespaced child returns first if absent is sorted last",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(orderedNamespacedReferences...)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    orderedNamespacedReferences[len(orderedNamespacedReferences)-1],
 | 
						|
			expectedAlternate: &orderedNamespacedReferences[0],
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "namespaced ref from namespaced child returns next after absent",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(orderedNamespacedReferences...)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    orderedNamespacedReferences[len(orderedNamespacedReferences)-2],
 | 
						|
			expectedAlternate: &orderedNamespacedReferences[len(orderedNamespacedReferences)-1],
 | 
						|
		},
 | 
						|
 | 
						|
		{
 | 
						|
			name: "cluster ref from cluster child returns first if absent is sorted last",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(clusterchild1, withOwners(orderedClusterReferences...)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    orderedClusterReferences[len(orderedClusterReferences)-1],
 | 
						|
			expectedAlternate: &orderedClusterReferences[0],
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "cluster ref from cluster child returns next after absent",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(clusterchild1, withOwners(orderedClusterReferences...)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    orderedClusterReferences[len(orderedClusterReferences)-2],
 | 
						|
			expectedAlternate: &orderedClusterReferences[len(orderedClusterReferences)-1],
 | 
						|
		},
 | 
						|
 | 
						|
		{
 | 
						|
			name: "ignore unrelated",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(clusterabsentparent, makeID("v1", "Parent", "ns1", "name", "anotheruid"))),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    clusterabsentparent,
 | 
						|
			expectedAlternate: nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "ignore matches",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(ns1child1, withOwners(clusterabsentparent, clusterabsentparent)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    clusterabsentparent,
 | 
						|
			expectedAlternate: nil,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "collapse duplicates",
 | 
						|
			deps: []*node{
 | 
						|
				makeNode(clusterchild1, withOwners(clusterabsentparent, clusterabsentparent_kind, clusterabsentparent_kind)),
 | 
						|
			},
 | 
						|
			verifiedAbsent:    clusterabsentparent,
 | 
						|
			expectedAlternate: &clusterabsentparent_kind,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, tc := range testcases {
 | 
						|
		t.Run(tc.name, func(t *testing.T) {
 | 
						|
			alternate := getAlternateOwnerIdentity(tc.deps, tc.verifiedAbsent)
 | 
						|
			if !reflect.DeepEqual(alternate, tc.expectedAlternate) {
 | 
						|
				t.Errorf("expected\n%#v\ngot\n%#v", tc.expectedAlternate, alternate)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |