github.com/kubewharf/katalyst-core@v0.5.3/pkg/controller/monitor/cnr_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 monitor 18 19 import ( 20 "context" 21 "testing" 22 "time" 23 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 corev1 "k8s.io/api/core/v1" 27 v1 "k8s.io/api/core/v1" 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 "k8s.io/apimachinery/pkg/runtime" 30 "k8s.io/client-go/tools/cache" 31 32 "github.com/kubewharf/katalyst-api/pkg/apis/node/v1alpha1" 33 katalyst_base "github.com/kubewharf/katalyst-core/cmd/base" 34 "github.com/kubewharf/katalyst-core/cmd/katalyst-agent/app/options" 35 metricspool "github.com/kubewharf/katalyst-core/pkg/metrics/metrics-pool" 36 ) 37 38 func TestCNRMonitor_Run(t *testing.T) { 39 t.Parallel() 40 41 oldPod := &corev1.Pod{ 42 ObjectMeta: metav1.ObjectMeta{ 43 Name: "pod1", 44 Namespace: "default", 45 UID: "uid1", 46 }, 47 Spec: corev1.PodSpec{ 48 NodeName: "", 49 }, 50 } 51 52 type fields struct { 53 pod *corev1.Pod 54 cnr *v1alpha1.CustomNodeResource 55 } 56 tests := []struct { 57 name string 58 fields fields 59 }{ 60 { 61 name: "test-pod-nodename-updated", 62 fields: fields{ 63 pod: &corev1.Pod{ 64 ObjectMeta: metav1.ObjectMeta{ 65 Name: "pod1", 66 Namespace: "default", 67 UID: "uid1", 68 }, 69 Spec: corev1.PodSpec{ 70 NodeName: "node1", 71 }, 72 }, 73 cnr: &v1alpha1.CustomNodeResource{ 74 ObjectMeta: metav1.ObjectMeta{ 75 Name: "test", 76 Labels: map[string]string{ 77 "test": "test", 78 }, 79 }, 80 }, 81 }, 82 }, 83 } 84 for _, tt := range tests { 85 tt := tt 86 t.Run(tt.name, func(t *testing.T) { 87 t.Parallel() 88 89 genericCtx, err := katalyst_base.GenerateFakeGenericContext([]runtime.Object{oldPod}, []runtime.Object{tt.fields.cnr}) 90 assert.NoError(t, err) 91 92 conf, err := options.NewOptions().Config() 93 require.NoError(t, err) 94 require.NotNil(t, conf) 95 96 ctrl, err := NewCNRMonitorController( 97 context.Background(), 98 conf.GenericConfiguration, 99 conf.GenericControllerConfiguration, 100 conf.CNRMonitorConfig, 101 genericCtx.Client, 102 genericCtx.KubeInformerFactory.Core().V1().Nodes(), 103 genericCtx.KubeInformerFactory.Core().V1().Pods(), 104 genericCtx.InternalInformerFactory.Node().V1alpha1().CustomNodeResources(), 105 metricspool.DummyMetricsEmitterPool.GetDefaultMetricsEmitter(metricspool.DummyMetricsEmitterPool{}), 106 ) 107 assert.NoError(t, err) 108 109 // test cache synced 110 genericCtx.KubeInformerFactory.Start(ctrl.ctx.Done()) 111 genericCtx.InternalInformerFactory.Start(ctrl.ctx.Done()) 112 go ctrl.Run() 113 114 cache.WaitForCacheSync(ctrl.ctx.Done(), ctrl.cnrListerSynced, ctrl.podListerSynced) 115 time.Sleep(100 * time.Millisecond) 116 117 gotCNR, err := ctrl.cnrLister.Get(tt.fields.cnr.Name) 118 assert.NoError(t, err) 119 assert.Equal(t, tt.fields.cnr, gotCNR) 120 121 gotPod, err := ctrl.podLister.Pods(oldPod.Namespace).Get(oldPod.Name) 122 assert.NoError(t, err) 123 assert.Equal(t, oldPod, gotPod) 124 125 // test schedule pod to node 126 _, err = genericCtx.Client.KubeClient.CoreV1().Pods(tt.fields.pod.Namespace).Update(ctrl.ctx, tt.fields.pod, metav1.UpdateOptions{}) 127 assert.NoError(t, err) 128 time.Sleep(100 * time.Millisecond) 129 }) 130 } 131 } 132 133 func Test_gcPodTimeMap(t *testing.T) { 134 t.Parallel() 135 136 var ( 137 time1 = time.Now().Add(-6 * time.Minute) 138 time2 = time.Now().Add(-time.Second) 139 ) 140 type args struct { 141 pod *corev1.Pod 142 podTimeMap map[string]time.Time 143 } 144 tests := []struct { 145 name string 146 args args 147 want map[string]time.Time 148 }{ 149 { 150 name: "test-gc and emit timeout cnr report lantency metric", 151 args: args{ 152 pod: &corev1.Pod{ 153 ObjectMeta: metav1.ObjectMeta{ 154 Name: "pod1", 155 Namespace: "test", 156 }, 157 Spec: corev1.PodSpec{ 158 Containers: []corev1.Container{ 159 { 160 Name: "container-1", 161 Image: "nginx:latest", 162 }, 163 }, 164 }, 165 Status: corev1.PodStatus{ 166 Phase: v1.PodRunning, 167 ContainerStatuses: []corev1.ContainerStatus{ 168 { 169 Name: "container-1", 170 Ready: true, 171 RestartCount: 0, 172 }, 173 }, 174 }, 175 }, 176 podTimeMap: map[string]time.Time{ 177 "test/pod1/1": time1, 178 "test/pod2/2": time2, 179 }, 180 }, 181 want: map[string]time.Time{ 182 "test/pod2/2": time2, 183 }, 184 }, 185 { 186 name: "test-no-gc", 187 args: args{ 188 podTimeMap: map[string]time.Time{ 189 "test/pod1/1": time2, 190 }, 191 }, 192 want: map[string]time.Time{ 193 "test/pod1/1": time2, 194 }, 195 }, 196 { 197 name: "test-empty", 198 args: args{ 199 podTimeMap: map[string]time.Time{}, 200 }, 201 want: map[string]time.Time{}, 202 }, 203 } 204 for _, tt := range tests { 205 tt := tt 206 t.Run(tt.name, func(t *testing.T) { 207 t.Parallel() 208 209 genericCtx, err := katalyst_base.GenerateFakeGenericContext([]runtime.Object{tt.args.pod}, []runtime.Object{}) 210 assert.NoError(t, err) 211 212 conf, err := options.NewOptions().Config() 213 require.NoError(t, err) 214 require.NotNil(t, conf) 215 216 ctrl, err := NewCNRMonitorController( 217 context.Background(), 218 conf.GenericConfiguration, 219 conf.GenericControllerConfiguration, 220 conf.CNRMonitorConfig, 221 genericCtx.Client, 222 genericCtx.KubeInformerFactory.Core().V1().Nodes(), 223 genericCtx.KubeInformerFactory.Core().V1().Pods(), 224 genericCtx.InternalInformerFactory.Node().V1alpha1().CustomNodeResources(), 225 metricspool.DummyMetricsEmitterPool.GetDefaultMetricsEmitter(metricspool.DummyMetricsEmitterPool{}), 226 ) 227 assert.NoError(t, err) 228 229 // test cache synced 230 genericCtx.KubeInformerFactory.Start(ctrl.ctx.Done()) 231 genericCtx.InternalInformerFactory.Start(ctrl.ctx.Done()) 232 233 cache.WaitForCacheSync(ctrl.ctx.Done(), ctrl.cnrListerSynced, ctrl.podListerSynced) 234 time.Sleep(100 * time.Millisecond) 235 236 for k, v := range tt.args.podTimeMap { 237 ctrl.podTimeMap.Store(k, v) 238 } 239 240 ctrl.gcPodTimeMap() 241 242 podTimeMap := map[string]time.Time{} 243 ctrl.podTimeMap.Range(func(k, v interface{}) bool { 244 podTimeMap[k.(string)] = v.(time.Time) 245 return true 246 }) 247 248 assert.Equal(t, tt.want, podTimeMap) 249 }) 250 } 251 }