...

Source file src/k8s.io/kubernetes/pkg/controller/garbagecollector/graph_builder_test.go

Documentation: k8s.io/kubernetes/pkg/controller/garbagecollector

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package garbagecollector
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  )
    23  
    24  func TestGetAlternateOwnerIdentity(t *testing.T) {
    25  	ns1child1 := makeID("v1", "Child", "ns1", "child1", "childuid11")
    26  	ns1child2 := makeID("v1", "Child", "ns1", "child2", "childuid12")
    27  
    28  	ns2child1 := makeID("v1", "Child", "ns2", "child1", "childuid21")
    29  
    30  	clusterchild1 := makeID("v1", "Child", "", "child1", "childuidc1")
    31  
    32  	var (
    33  		nsabsentparentns1 = makeID("v1", "NSParent", "ns1", "parentname", "parentuid")
    34  		nsabsentparentns2 = makeID("v1", "NSParent", "ns2", "parentname", "parentuid")
    35  
    36  		nsabsentparent_version = makeID("xx", "NSParent", "ns1", "parentname", "parentuid")
    37  		nsabsentparent_kind    = makeID("v1", "xxxxxxxx", "ns1", "parentname", "parentuid")
    38  		nsabsentparent_name    = makeID("v1", "NSParent", "ns1", "xxxxxxxxxx", "parentuid")
    39  
    40  		clusterabsentparent         = makeID("v1", "ClusterParent", "", "parentname", "parentuid")
    41  		clusterabsentparent_version = makeID("xx", "ClusterParent", "", "parentname", "parentuid")
    42  		clusterabsentparent_kind    = makeID("v1", "xxxxxxxxxxxxx", "", "parentname", "parentuid")
    43  		clusterabsentparent_name    = makeID("v1", "ClusterParent", "", "xxxxxxxxxx", "parentuid")
    44  
    45  		clusterabsentparent_ns1_version = makeID("xx", "ClusterParent", "ns1", "parentname", "parentuid")
    46  		clusterabsentparent_ns1_kind    = makeID("v1", "xxxxxxxxxxxxx", "ns1", "parentname", "parentuid")
    47  	)
    48  
    49  	orderedNamespacedReferences := []objectReference{
    50  		makeID("v1", "kind", "ns1", "name", "uid"),
    51  		makeID("v2", "kind", "ns1", "name", "uid"),
    52  		makeID("v3", "kind", "ns1", "name", "uid"),
    53  		makeID("v4", "kind", "ns1", "name", "uid"),
    54  		makeID("v5", "kind", "ns1", "name", "uid"),
    55  	}
    56  	orderedClusterReferences := []objectReference{
    57  		makeID("v1", "kind", "", "name", "uid"),
    58  		makeID("v2", "kind", "", "name", "uid"),
    59  		makeID("v3", "kind", "", "name", "uid"),
    60  		makeID("v4", "kind", "", "name", "uid"),
    61  		makeID("v5", "kind", "", "name", "uid"),
    62  	}
    63  
    64  	testcases := []struct {
    65  		name              string
    66  		deps              []*node
    67  		verifiedAbsent    objectReference
    68  		expectedAlternate *objectReference
    69  	}{
    70  		{
    71  			name: "namespaced alternate version",
    72  			deps: []*node{
    73  				makeNode(ns1child1, withOwners(nsabsentparentns1)),
    74  				makeNode(ns1child2, withOwners(nsabsentparent_version)),
    75  			},
    76  			verifiedAbsent:    nsabsentparentns1,
    77  			expectedAlternate: &nsabsentparent_version, // switch to alternate version
    78  		},
    79  		{
    80  			name: "namespaced alternate kind",
    81  			deps: []*node{
    82  				makeNode(ns1child1, withOwners(nsabsentparentns1)),
    83  				makeNode(ns1child2, withOwners(nsabsentparent_kind)),
    84  			},
    85  			verifiedAbsent:    nsabsentparentns1,
    86  			expectedAlternate: &nsabsentparent_kind, // switch to alternate kind
    87  		},
    88  		{
    89  			name: "namespaced alternate namespace",
    90  			deps: []*node{
    91  				makeNode(ns1child1, withOwners(nsabsentparentns1)),
    92  				makeNode(ns2child1, withOwners(nsabsentparentns2)),
    93  			},
    94  			verifiedAbsent:    nsabsentparentns1,
    95  			expectedAlternate: &nsabsentparentns2, // switch to alternate namespace
    96  		},
    97  		{
    98  			name: "namespaced alternate name",
    99  			deps: []*node{
   100  				makeNode(ns1child1, withOwners(nsabsentparentns1)),
   101  				makeNode(ns1child1, withOwners(nsabsentparent_name)),
   102  			},
   103  			verifiedAbsent:    nsabsentparentns1,
   104  			expectedAlternate: &nsabsentparent_name, // switch to alternate name
   105  		},
   106  
   107  		{
   108  			name: "cluster alternate version",
   109  			deps: []*node{
   110  				makeNode(ns1child1, withOwners(clusterabsentparent)),
   111  				makeNode(ns1child2, withOwners(clusterabsentparent_version)),
   112  			},
   113  			verifiedAbsent:    clusterabsentparent,
   114  			expectedAlternate: &clusterabsentparent_ns1_version, // switch to alternate version, namespaced to new dependent since we don't know the version is cluster-scoped
   115  		},
   116  		{
   117  			name: "cluster alternate kind",
   118  			deps: []*node{
   119  				makeNode(ns1child1, withOwners(clusterabsentparent)),
   120  				makeNode(ns1child2, withOwners(clusterabsentparent_kind)),
   121  			},
   122  			verifiedAbsent:    clusterabsentparent,
   123  			expectedAlternate: &clusterabsentparent_ns1_kind, // switch to alternate kind, namespaced to new dependent since we don't know the new kind is cluster-scoped
   124  		},
   125  		{
   126  			name: "cluster alternate namespace",
   127  			deps: []*node{
   128  				makeNode(ns1child1, withOwners(clusterabsentparent)),
   129  				makeNode(ns2child1, withOwners(clusterabsentparent)),
   130  			},
   131  			verifiedAbsent:    clusterabsentparent,
   132  			expectedAlternate: nil, // apiVersion/kind verified cluster-scoped, namespace delta ignored, no alternates found
   133  		},
   134  		{
   135  			name: "cluster alternate name",
   136  			deps: []*node{
   137  				makeNode(ns1child1, withOwners(clusterabsentparent)),
   138  				makeNode(ns1child1, withOwners(clusterabsentparent_name)),
   139  			},
   140  			verifiedAbsent:    clusterabsentparent,
   141  			expectedAlternate: &clusterabsentparent_name, // switch to alternate name, apiVersion/kind verified cluster-scoped, namespace dropped
   142  		},
   143  
   144  		{
   145  			name: "namespaced ref from namespaced child returns first if absent is sorted last",
   146  			deps: []*node{
   147  				makeNode(ns1child1, withOwners(orderedNamespacedReferences...)),
   148  			},
   149  			verifiedAbsent:    orderedNamespacedReferences[len(orderedNamespacedReferences)-1],
   150  			expectedAlternate: &orderedNamespacedReferences[0],
   151  		},
   152  		{
   153  			name: "namespaced ref from namespaced child returns next after absent",
   154  			deps: []*node{
   155  				makeNode(ns1child1, withOwners(orderedNamespacedReferences...)),
   156  			},
   157  			verifiedAbsent:    orderedNamespacedReferences[len(orderedNamespacedReferences)-2],
   158  			expectedAlternate: &orderedNamespacedReferences[len(orderedNamespacedReferences)-1],
   159  		},
   160  
   161  		{
   162  			name: "cluster ref from cluster child returns first if absent is sorted last",
   163  			deps: []*node{
   164  				makeNode(clusterchild1, withOwners(orderedClusterReferences...)),
   165  			},
   166  			verifiedAbsent:    orderedClusterReferences[len(orderedClusterReferences)-1],
   167  			expectedAlternate: &orderedClusterReferences[0],
   168  		},
   169  		{
   170  			name: "cluster ref from cluster child returns next after absent",
   171  			deps: []*node{
   172  				makeNode(clusterchild1, withOwners(orderedClusterReferences...)),
   173  			},
   174  			verifiedAbsent:    orderedClusterReferences[len(orderedClusterReferences)-2],
   175  			expectedAlternate: &orderedClusterReferences[len(orderedClusterReferences)-1],
   176  		},
   177  
   178  		{
   179  			name: "ignore unrelated",
   180  			deps: []*node{
   181  				makeNode(ns1child1, withOwners(clusterabsentparent, makeID("v1", "Parent", "ns1", "name", "anotheruid"))),
   182  			},
   183  			verifiedAbsent:    clusterabsentparent,
   184  			expectedAlternate: nil,
   185  		},
   186  		{
   187  			name: "ignore matches",
   188  			deps: []*node{
   189  				makeNode(ns1child1, withOwners(clusterabsentparent, clusterabsentparent)),
   190  			},
   191  			verifiedAbsent:    clusterabsentparent,
   192  			expectedAlternate: nil,
   193  		},
   194  		{
   195  			name: "collapse duplicates",
   196  			deps: []*node{
   197  				makeNode(clusterchild1, withOwners(clusterabsentparent, clusterabsentparent_kind, clusterabsentparent_kind)),
   198  			},
   199  			verifiedAbsent:    clusterabsentparent,
   200  			expectedAlternate: &clusterabsentparent_kind,
   201  		},
   202  	}
   203  
   204  	for _, tc := range testcases {
   205  		t.Run(tc.name, func(t *testing.T) {
   206  			alternate := getAlternateOwnerIdentity(tc.deps, tc.verifiedAbsent)
   207  			if !reflect.DeepEqual(alternate, tc.expectedAlternate) {
   208  				t.Errorf("expected\n%#v\ngot\n%#v", tc.expectedAlternate, alternate)
   209  			}
   210  		})
   211  	}
   212  }
   213  

View as plain text