github.com/kubewharf/katalyst-core@v0.5.3/pkg/util/resource-recommend/log/logger_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 log 18 19 import ( 20 "context" 21 "flag" 22 "fmt" 23 "os" 24 "regexp" 25 "runtime" 26 "testing" 27 28 "k8s.io/klog/v2" 29 ) 30 31 func TestInitContextAndGetCtxFields(t *testing.T) { 32 type args struct { 33 ctx context.Context 34 } 35 tests := []struct { 36 name string 37 args args 38 }{ 39 { 40 name: "case1", 41 args: args{ 42 ctx: context.Background(), 43 }, 44 }, 45 } 46 for _, tt := range tests { 47 t.Run(tt.name, func(t *testing.T) { 48 ctx := InitContext(tt.args.ctx) 49 fields := GetCtxFields(ctx) 50 if len(fields) != 2 { 51 t.Errorf("The fields length must be 2") 52 } 53 if fields[0] != LinkIDKey { 54 t.Errorf("fields must be included: %s", LinkIDKey) 55 } 56 }) 57 } 58 } 59 60 func TestSetKeysAndValues(t *testing.T) { 61 type tempStruct struct { 62 a int 63 b string 64 } 65 tempStruct1 := &tempStruct{111, "aaa"} 66 type args struct { 67 ctx context.Context 68 keysAndValues []interface{} 69 } 70 type want struct { 71 index int 72 wantValue interface{} 73 } 74 tests := []struct { 75 name string 76 args args 77 want []want 78 }{ 79 { 80 name: "case1", 81 args: args{ 82 ctx: InitContext(context.Background()), 83 keysAndValues: []interface{}{"k1", "v1", "k2", "v2"}, 84 }, 85 want: []want{ 86 { 87 index: 2, wantValue: "k1", 88 }, 89 { 90 index: 3, wantValue: "v1", 91 }, 92 { 93 index: 4, wantValue: "k2", 94 }, 95 { 96 index: 5, wantValue: "v2", 97 }, 98 }, 99 }, 100 { 101 name: "case2", 102 args: args{ 103 ctx: InitContext(context.Background()), 104 keysAndValues: []interface{}{"k1", tempStruct{111, "aaa"}}, 105 }, 106 want: []want{ 107 { 108 index: 2, wantValue: "k1", 109 }, 110 { 111 index: 3, wantValue: tempStruct{111, "aaa"}, 112 }, 113 }, 114 }, 115 { 116 name: "case3", 117 args: args{ 118 ctx: InitContext(context.Background()), 119 keysAndValues: []interface{}{"k1", tempStruct1}, 120 }, 121 want: []want{ 122 { 123 index: 2, wantValue: "k1", 124 }, 125 { 126 index: 3, wantValue: tempStruct1, 127 }, 128 }, 129 }, 130 { 131 name: "case4", 132 args: args{ 133 ctx: context.Background(), 134 keysAndValues: []interface{}{"k1", tempStruct1}, 135 }, 136 want: []want{ 137 { 138 index: 0, wantValue: "k1", 139 }, 140 { 141 index: 1, wantValue: tempStruct1, 142 }, 143 }, 144 }, 145 { 146 name: "case4", 147 args: args{ 148 ctx: InitContext(context.Background()), 149 keysAndValues: []interface{}{}, 150 }, 151 want: []want{}, 152 }, 153 } 154 for _, tt := range tests { 155 t.Run(tt.name, func(t *testing.T) { 156 ctx := SetKeysAndValues(tt.args.ctx, tt.args.keysAndValues...) 157 fields := GetCtxFields(ctx) 158 for _, w := range tt.want { 159 if fields[w.index] != w.wantValue { 160 t.Errorf("set KeysAndValues error, index(%d) should be %v, got: %v", w.index, w.wantValue, fields[w.index]) 161 } else { 162 t.Logf("set KeysAndValues successful, index(%d) should be %v, got: %v", w.index, w.wantValue, fields[w.index]) 163 } 164 } 165 }) 166 } 167 } 168 169 // 自定义的测试日志记录器,实现 io.Writer 接口 170 type TestLogger struct { 171 RegularxEpression string 172 t *testing.T 173 } 174 175 func (tl *TestLogger) Write(p []byte) (n int, err error) { 176 str := string(p) 177 178 regex, err := regexp.Compile(tl.RegularxEpression) 179 if err != nil { 180 fmt.Println("Error compiling regex:", err) 181 return 182 } 183 isMatch := regex.MatchString(str) 184 if !isMatch { 185 tl.t.Errorf("match the log content error, regex is %s, got: %s", tl.RegularxEpression, str) 186 } 187 188 return len(p), nil 189 } 190 191 func TestErrorS(t *testing.T) { 192 type args struct { 193 ctx context.Context 194 err error 195 msg string 196 keysAndValues []interface{} 197 } 198 tests := []struct { 199 name string 200 args args 201 wantLogStr string 202 }{ 203 { 204 name: "case1", 205 args: args{ 206 ctx: SetKeysAndValues(context.Background(), "baseK1", "baseV1"), 207 err: fmt.Errorf("err1"), 208 msg: "errMsg1", 209 keysAndValues: []interface{}{"k1", "v1", "k2", "v2"}, 210 }, 211 wantLogStr: "E\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{6} %d logger_test.go:%d] \"errMsg1\" err=\"err1\" baseK1=\"baseV1\" k1=\"v1\" k2=\"v2\"\n", 212 }, 213 { 214 name: "case2", 215 args: args{ 216 ctx: context.Background(), 217 err: fmt.Errorf("err1"), 218 msg: "errMsg1", 219 keysAndValues: []interface{}{}, 220 }, 221 wantLogStr: "E\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{6} %d logger_test.go:%d] \"errMsg1\" err=\"err1\"\n", 222 }, 223 } 224 for _, tt := range tests { 225 t.Run(tt.name, func(t *testing.T) { 226 _, _, line, ok := runtime.Caller(0) 227 if !ok { 228 panic("Unable to retrieve caller information") 229 } 230 pid := os.Getpid() 231 klog.LogToStderr(false) 232 klog.SetOutput(&TestLogger{ 233 RegularxEpression: fmt.Sprintf(tt.wantLogStr, pid, line+10), 234 t: t, 235 }) 236 ErrorS(tt.args.ctx, tt.args.err, tt.args.msg, tt.args.keysAndValues...) 237 }) 238 } 239 } 240 241 func TestInfoS(t *testing.T) { 242 type args struct { 243 ctx context.Context 244 msg string 245 keysAndValues []interface{} 246 } 247 tests := []struct { 248 name string 249 args args 250 wantLogStr string 251 }{ 252 { 253 name: "case1", 254 args: args{ 255 ctx: SetKeysAndValues(context.Background(), "baseK1", "baseV1"), 256 msg: "InfoMsg1", 257 keysAndValues: []interface{}{"k1", "v1", "k2", "v2"}, 258 }, 259 wantLogStr: "I\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{6} %d logger_test.go:%d] \"InfoMsg1\" baseK1=\"baseV1\" k1=\"v1\" k2=\"v2\"\n", 260 }, 261 { 262 name: "case2", 263 args: args{ 264 ctx: context.Background(), 265 msg: "InfoMsg1", 266 keysAndValues: []interface{}{}, 267 }, 268 wantLogStr: "I\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{6} %d logger_test.go:%d] \"InfoMsg1\"\n", 269 }, 270 } 271 for _, tt := range tests { 272 t.Run(tt.name, func(t *testing.T) { 273 _, _, line, ok := runtime.Caller(0) 274 if !ok { 275 panic("Unable to retrieve caller information") 276 } 277 pid := os.Getpid() 278 klog.LogToStderr(false) 279 klog.SetOutput(&TestLogger{ 280 RegularxEpression: fmt.Sprintf(tt.wantLogStr, pid, line+10), 281 t: t, 282 }) 283 InfoS(tt.args.ctx, tt.args.msg, tt.args.keysAndValues...) 284 }) 285 } 286 } 287 288 func TestVerbose_InfoS(t *testing.T) { 289 logLevel := klog.Level(1) 290 klog.InitFlags(nil) 291 flag.Set("v", logLevel.String()) 292 flag.Parse() 293 294 type fields struct { 295 Verbose klog.Verbose 296 } 297 type args struct { 298 ctx context.Context 299 msg string 300 keysAndValues []interface{} 301 } 302 tests := []struct { 303 name string 304 fields fields 305 args args 306 wantLogStr string 307 }{ 308 { 309 name: "case1", 310 args: args{ 311 ctx: SetKeysAndValues(context.Background(), "baseK1", "baseV1"), 312 msg: "InfoMsg1", 313 keysAndValues: []interface{}{"k1", "v1", "k2", "v2"}, 314 }, 315 wantLogStr: "I\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{6} %d logger_test.go:%d] \"InfoMsg1\" baseK1=\"baseV1\" k1=\"v1\" k2=\"v2\"\n", 316 }, 317 { 318 name: "case2", 319 args: args{ 320 ctx: context.Background(), 321 msg: "InfoMsg1", 322 keysAndValues: []interface{}{}, 323 }, 324 wantLogStr: "I\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{6} %d logger_test.go:%d] \"InfoMsg1\"\n", 325 }, 326 } 327 for _, tt := range tests { 328 t.Run(tt.name, func(t *testing.T) { 329 _, _, line, ok := runtime.Caller(0) 330 if !ok { 331 panic("Unable to retrieve caller information") 332 } 333 pid := os.Getpid() 334 klog.LogToStderr(false) 335 klog.SetOutput(&TestLogger{ 336 RegularxEpression: fmt.Sprintf(tt.wantLogStr, pid, line+10), 337 t: t, 338 }) 339 V(logLevel).InfoS(tt.args.ctx, tt.args.msg, tt.args.keysAndValues...) 340 klog.Flush() 341 }) 342 } 343 }