...

Source file src/k8s.io/kubernetes/pkg/controlplane/controller/systemnamespaces/system_namespaces_controller_test.go

Documentation: k8s.io/kubernetes/pkg/controlplane/controller/systemnamespaces

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

View as plain text