k8s.io/kubernetes@v1.29.3/pkg/controlplane/controller/systemnamespaces/system_namespaces_controller_test.go (about) 1 /* 2 Copyright 2023 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 systemnamespaces 18 19 import ( 20 "testing" 21 22 v1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/labels" 25 "k8s.io/apimachinery/pkg/runtime" 26 "k8s.io/client-go/informers" 27 "k8s.io/client-go/kubernetes/fake" 28 k8stesting "k8s.io/client-go/testing" 29 "k8s.io/gengo/examples/set-gen/sets" 30 ) 31 32 // Test_Controller validates the garbage collection logic for the apiserverleasegc controller. 33 func Test_Controller(t *testing.T) { 34 systemNamespaces := []string{metav1.NamespaceSystem, metav1.NamespacePublic, v1.NamespaceNodeLease} 35 36 tests := []struct { 37 name string 38 namespaces []string 39 actions [][]string // verb and resource 40 }{ 41 { 42 name: "no system namespaces", 43 actions: [][]string{ 44 {"create", "namespaces"}, 45 {"create", "namespaces"}, 46 {"create", "namespaces"}, 47 {"create", "namespaces"}, 48 }, 49 }, 50 { 51 name: "no system namespaces but others", 52 namespaces: []string{"foo", "bar"}, 53 actions: [][]string{ 54 {"create", "namespaces"}, 55 {"create", "namespaces"}, 56 {"create", "namespaces"}, 57 {"create", "namespaces"}, 58 }, 59 }, 60 { 61 name: "one system namespace", 62 namespaces: []string{metav1.NamespaceSystem}, 63 actions: [][]string{ 64 {"create", "namespaces"}, 65 {"create", "namespaces"}, 66 {"create", "namespaces"}, 67 }, 68 }, 69 { 70 name: "two system namespaces", 71 namespaces: []string{metav1.NamespaceSystem, metav1.NamespacePublic}, 72 actions: [][]string{ 73 {"create", "namespaces"}, 74 {"create", "namespaces"}, 75 }, 76 }, 77 { 78 name: "three namespaces", 79 namespaces: []string{metav1.NamespaceSystem, metav1.NamespacePublic, v1.NamespaceNodeLease}, 80 actions: [][]string{ 81 {"create", "namespaces"}, 82 }, 83 }, 84 85 { 86 name: "the four namespaces", 87 namespaces: []string{metav1.NamespaceSystem, metav1.NamespacePublic, v1.NamespaceNodeLease, v1.NamespaceDefault}, 88 }, 89 } 90 91 for _, test := range tests { 92 t.Run(test.name, func(t *testing.T) { 93 objs := []runtime.Object{} 94 for _, ns := range test.namespaces { 95 objs = append(objs, 96 &v1.Namespace{ 97 ObjectMeta: metav1.ObjectMeta{ 98 Name: ns, 99 Namespace: "", 100 }, 101 }, 102 ) 103 } 104 clientset := fake.NewSimpleClientset(objs...) 105 informerFactory := informers.NewSharedInformerFactory(clientset, 0) 106 namespaceInformer := informerFactory.Core().V1().Namespaces() 107 for _, obj := range objs { 108 namespaceInformer.Informer().GetIndexer().Add(obj) 109 } 110 111 controller := NewController(clientset, namespaceInformer) 112 113 clientset.PrependReactor("create", "namespaces", func(action k8stesting.Action) (bool, runtime.Object, error) { 114 create := action.(k8stesting.CreateAction) 115 namespaceInformer.Informer().GetIndexer().Add(create.GetObject()) 116 return true, create.GetObject(), nil 117 }) 118 119 controller.sync() 120 121 expectAction(t, clientset.Actions(), test.actions) 122 namespaces, err := controller.namespaceLister.List(labels.Everything()) 123 if err != nil { 124 t.Errorf("unexpected error: %v", err) 125 } 126 127 got := sets.NewString() 128 for _, ns := range namespaces { 129 got.Insert(ns.Name) 130 } 131 132 if !got.HasAll(systemNamespaces...) { 133 t.Errorf("unexpected namespaces: %v", got.List()) 134 } 135 }) 136 } 137 } 138 139 func expectAction(t *testing.T, actions []k8stesting.Action, expected [][]string) { 140 t.Helper() 141 if len(actions) != len(expected) { 142 t.Fatalf("Expected at least %d actions, got %d", len(expected), len(actions)) 143 } 144 145 for i, action := range actions { 146 verb := expected[i][0] 147 if action.GetVerb() != verb { 148 t.Errorf("Expected action %d verb to be %s, got %s", i, verb, action.GetVerb()) 149 } 150 resource := expected[i][1] 151 if action.GetResource().Resource != resource { 152 t.Errorf("Expected action %d resource to be %s, got %s", i, resource, action.GetResource().Resource) 153 } 154 } 155 }