github.com/kubewharf/katalyst-core@v0.5.3/pkg/controller/lifecycle/agent-healthz/healthz_controller_test.go (about) 1 /* 2 Copyright 2022 The Katalyst 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 agent_healthz 18 19 import ( 20 "context" 21 "fmt" 22 "testing" 23 "time" 24 25 "github.com/stretchr/testify/assert" 26 "github.com/stretchr/testify/require" 27 corev1 "k8s.io/api/core/v1" 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 "k8s.io/apimachinery/pkg/labels" 30 "k8s.io/apimachinery/pkg/runtime" 31 utilruntime "k8s.io/apimachinery/pkg/util/runtime" 32 "k8s.io/client-go/informers" 33 "k8s.io/client-go/kubernetes/fake" 34 "k8s.io/client-go/tools/cache" 35 "k8s.io/klog/v2" 36 37 apis "github.com/kubewharf/katalyst-api/pkg/apis/node/v1alpha1" 38 internalfake "github.com/kubewharf/katalyst-api/pkg/client/clientset/versioned/fake" 39 "github.com/kubewharf/katalyst-api/pkg/client/informers/externalversions" 40 "github.com/kubewharf/katalyst-core/cmd/katalyst-controller/app/options" 41 "github.com/kubewharf/katalyst-core/pkg/client" 42 pkgconfig "github.com/kubewharf/katalyst-core/pkg/config" 43 ) 44 45 func generateTestKubeClientSet(objects []runtime.Object, internalObjects []runtime.Object) *client.GenericClientSet { 46 return &client.GenericClientSet{ 47 KubeClient: fake.NewSimpleClientset(objects...), 48 InternalClient: internalfake.NewSimpleClientset(internalObjects...), 49 } 50 } 51 52 func generateTestConfiguration(t *testing.T) *pkgconfig.Configuration { 53 seletor, _ := labels.Parse("app=katalyst-agent") 54 55 testConfiguration, err := options.NewOptions().Config() 56 require.NoError(t, err) 57 require.NotNil(t, testConfiguration) 58 testConfiguration.ControllersConfiguration.LifeCycleConfig.HandlePeriod = time.Second 59 testConfiguration.ControllersConfiguration.LifeCycleConfig.UnhealthyPeriods = 5 * time.Second 60 testConfiguration.ControllersConfiguration.LifeCycleConfig.AgentSelector = map[string]labels.Selector{ 61 "katalyst-agent": seletor, 62 } 63 64 return testConfiguration 65 } 66 67 func NewFakeHealthzController(t *testing.T) (*HealthzController, error) { 68 stopCh := make(chan struct{}) 69 defer close(stopCh) 70 71 label := make(map[string]string) 72 label["app"] = "katalyst-agent" 73 74 pod := &corev1.Pod{ 75 ObjectMeta: metav1.ObjectMeta{ 76 Name: "pod1", 77 Labels: label, 78 }, 79 Spec: corev1.PodSpec{ 80 NodeName: "node1", 81 Containers: []corev1.Container{ 82 { 83 Name: "katalyst-agent", 84 }, 85 }, 86 }, 87 Status: corev1.PodStatus{ 88 ContainerStatuses: []corev1.ContainerStatus{ 89 {Ready: true}, 90 }, 91 }, 92 } 93 94 node := &corev1.Node{ 95 ObjectMeta: metav1.ObjectMeta{ 96 Name: "node1", 97 UID: "1", 98 }, 99 Spec: corev1.NodeSpec{}, 100 } 101 102 cnr := &apis.CustomNodeResource{ 103 ObjectMeta: metav1.ObjectMeta{ 104 Name: "node1", 105 }, 106 Spec: apis.CustomNodeResourceSpec{ 107 Taints: []*apis.Taint{}, 108 }, 109 Status: apis.CustomNodeResourceStatus{}, 110 } 111 112 clientSet := generateTestKubeClientSet([]runtime.Object{pod, node}, []runtime.Object{cnr}) 113 kubeInformerFactory := informers.NewSharedInformerFactoryWithOptions(clientSet.KubeClient, time.Hour*24) 114 nodeInformer := kubeInformerFactory.Core().V1().Nodes() 115 podInformer := kubeInformerFactory.Core().V1().Pods() 116 117 internalInformerFactory := externalversions.NewSharedInformerFactoryWithOptions(clientSet.InternalClient, time.Hour*24) 118 cnrInformer := internalInformerFactory.Node().V1alpha1().CustomNodeResources() 119 120 conf := generateTestConfiguration(t) 121 ec, err := NewHealthzController(context.Background(), conf.GenericConfiguration, conf.GenericControllerConfiguration, 122 conf.ControllersConfiguration.LifeCycleConfig, clientSet, nodeInformer, podInformer, cnrInformer, nil) 123 if err != nil { 124 t.Errorf("new eviction controller error") 125 } 126 127 kubeInformerFactory.Start(stopCh) 128 internalInformerFactory.Start(stopCh) 129 130 if !cache.WaitForCacheSync(ec.ctx.Done(), ec.nodeListerSynced, ec.cnrListerSynced, ec.podListerSynced) { 131 utilruntime.HandleError(fmt.Errorf("unable to sync caches for evcition controller")) 132 } 133 return ec, nil 134 } 135 136 func TestHealthzController(t *testing.T) { 137 t.Parallel() 138 139 ec, err := NewFakeHealthzController(t) 140 if err != nil { 141 klog.Errorf("get new fake cnr lifecycle err %v", err) 142 } 143 144 go ec.Run() 145 146 healthy := ec.healthzHelper.CheckAllAgentReady("node1") 147 assert.Equal(t, true, healthy) 148 } 149 150 func Test_podTransformerFunc(t *testing.T) { 151 t.Parallel() 152 153 type args struct { 154 src *corev1.Pod 155 dest *corev1.Pod 156 } 157 tests := []struct { 158 name string 159 args args 160 want *corev1.Pod 161 }{ 162 { 163 name: "normal", 164 args: args{ 165 src: &corev1.Pod{ 166 Spec: corev1.PodSpec{ 167 Containers: []corev1.Container{ 168 { 169 Name: "container-1", 170 }, 171 }, 172 NodeName: "node-1", 173 HostPID: true, 174 }, 175 Status: corev1.PodStatus{ 176 ContainerStatuses: []corev1.ContainerStatus{ 177 { 178 Name: "container-1", 179 Ready: true, 180 }, 181 }, 182 }, 183 }, 184 dest: &corev1.Pod{}, 185 }, 186 want: &corev1.Pod{ 187 Spec: corev1.PodSpec{ 188 Containers: []corev1.Container{ 189 { 190 Name: "container-1", 191 }, 192 }, 193 NodeName: "node-1", 194 }, 195 Status: corev1.PodStatus{ 196 ContainerStatuses: []corev1.ContainerStatus{ 197 { 198 Name: "container-1", 199 Ready: true, 200 }, 201 }, 202 }, 203 }, 204 }, 205 } 206 for _, tt := range tests { 207 tt := tt 208 t.Run(tt.name, func(t *testing.T) { 209 t.Parallel() 210 podTransformerFunc(tt.args.src, tt.args.dest) 211 assert.Equal(t, tt.want, tt.args.dest) 212 }) 213 } 214 }