github.com/matrixorigin/matrixone@v0.7.0/pkg/logutil/internal_test.go (about) 1 // Copyright 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package logutil 16 17 import ( 18 "context" 19 "github.com/lni/goutils/leaktest" 20 "regexp" 21 "testing" 22 23 "github.com/stretchr/testify/require" 24 "go.uber.org/zap" 25 "go.uber.org/zap/zapcore" 26 27 "github.com/matrixorigin/matrixone/pkg/common/moerr" 28 ) 29 30 func TestLogConfig_getter(t *testing.T) { 31 type fields struct { 32 Level string 33 Format string 34 Filename string 35 MaxSize int 36 MaxDays int 37 MaxBackups int 38 39 Entry zapcore.Entry 40 } 41 tests := []struct { 42 name string 43 fields fields 44 wantLevel zap.AtomicLevel 45 wantOpts []zap.Option 46 wantSyncer zapcore.WriteSyncer 47 wantEncoder zapcore.Encoder 48 wantSinks []ZapSink 49 }{ 50 { 51 name: "normal", 52 fields: fields{ 53 Level: "debug", 54 Format: "console", 55 Filename: "", 56 MaxSize: 0, 57 MaxDays: 0, 58 MaxBackups: 0, 59 60 Entry: zapcore.Entry{Level: zapcore.DebugLevel, Message: "console msg"}, 61 }, 62 wantLevel: zap.NewAtomicLevelAt(zap.DebugLevel), 63 wantOpts: []zap.Option{zap.AddStacktrace(zapcore.FatalLevel), zap.AddCaller()}, 64 wantSyncer: getConsoleSyncer(), 65 wantEncoder: getLoggerEncoder("console"), 66 wantSinks: []ZapSink{{getLoggerEncoder("console"), getConsoleSyncer()}}, 67 }, 68 } 69 for _, tt := range tests { 70 t.Run(tt.name, func(t *testing.T) { 71 cfg := &LogConfig{ 72 Level: tt.fields.Level, 73 Format: tt.fields.Format, 74 Filename: tt.fields.Filename, 75 MaxSize: tt.fields.MaxSize, 76 MaxDays: tt.fields.MaxDays, 77 MaxBackups: tt.fields.MaxBackups, 78 79 DisableStore: true, 80 } 81 require.Equal(t, tt.wantLevel, cfg.getLevel()) 82 require.Equal(t, len(tt.wantOpts), len(cfg.getOptions())) 83 require.Equal(t, tt.wantSyncer, cfg.getSyncer()) 84 wantMsg, _ := tt.wantEncoder.EncodeEntry(tt.fields.Entry, nil) 85 gotMsg, _ := cfg.getEncoder().EncodeEntry(tt.fields.Entry, nil) 86 require.Equal(t, wantMsg.String(), gotMsg.String()) 87 require.Equal(t, len(tt.wantSinks), len(cfg.getSinks())) 88 }) 89 } 90 } 91 92 func TestSetupMOLogger(t *testing.T) { 93 defer leaktest.AfterTest(t)() 94 type args struct { 95 conf *LogConfig 96 } 97 tests := []struct { 98 name string 99 args args 100 }{ 101 { 102 name: "console", 103 args: args{conf: &LogConfig{ 104 Level: zapcore.DebugLevel.String(), 105 Format: "console", 106 Filename: "", 107 MaxSize: 512, 108 MaxDays: 0, 109 MaxBackups: 0, 110 111 DisableStore: true, 112 }}, 113 }, 114 { 115 name: "json", 116 args: args{conf: &LogConfig{ 117 Level: zapcore.DebugLevel.String(), 118 Format: "json", 119 Filename: "", 120 MaxSize: 512, 121 MaxDays: 0, 122 MaxBackups: 0, 123 124 DisableStore: true, 125 }}, 126 }, 127 /*{ 128 // fix gopkg.in/natefinch/lumberjack.v2@v2.0.0/lumberjack.go:390 have a background goroutine for rotate-log 129 name: "json", 130 args: args{conf: &LogConfig{ 131 Level: zapcore.DebugLevel.String(), 132 Format: "json", 133 Filename: path.Join(t.TempDir(), "json.log"), 134 MaxSize: 0, 135 MaxDays: 0, 136 MaxBackups: 0, 137 138 DisableStore: true, 139 }}, 140 },*/ 141 } 142 for _, tt := range tests { 143 t.Run(tt.name, func(t *testing.T) { 144 SetupMOLogger(tt.args.conf) 145 }) 146 } 147 } 148 149 func TestSetupMOLogger_panic(t *testing.T) { 150 defer leaktest.AfterTest(t)() 151 type args struct { 152 conf *LogConfig 153 } 154 tests := []struct { 155 name string 156 args args 157 }{ 158 { 159 name: "panic", 160 args: args{conf: &LogConfig{ 161 Level: zapcore.DebugLevel.String(), 162 Format: "panic", 163 Filename: "", 164 MaxSize: 512, 165 MaxDays: 0, 166 MaxBackups: 0, 167 }}, 168 }, 169 } 170 for _, tt := range tests { 171 t.Run(tt.name, func(t *testing.T) { 172 defer func() { 173 if err := recover(); err != nil { 174 require.Equal(t, moerr.NewInternalError(context.TODO(), "unsupported log format: %s", tt.args.conf.Format), err) 175 } else { 176 t.Errorf("not receive panic") 177 } 178 }() 179 SetupMOLogger(tt.args.conf) 180 }) 181 } 182 } 183 184 func Test_getLoggerEncoder(t *testing.T) { 185 defer leaktest.AfterTest(t)() 186 type args struct { 187 format string 188 } 189 type fields struct { 190 entry zapcore.Entry 191 fields []zap.Field 192 } 193 tests := []struct { 194 name string 195 args args 196 fields fields 197 wantOutput *regexp.Regexp 198 foundCnt int 199 }{ 200 { 201 name: "console", 202 args: args{ 203 format: "console", 204 }, 205 fields: fields{ 206 entry: zapcore.Entry{Level: zapcore.DebugLevel, Message: "console msg"}, 207 fields: []zap.Field{}, 208 }, 209 // like: 0001/01/01 00:00:00.000000 +0000 DEBUG console msg 210 wantOutput: regexp.MustCompile(`\d{4}/\d{2}/\d{2} (\d{2}:{0,1}){3}\.\d{6} \+\d{4} DEBUG console msg`), 211 foundCnt: 1, 212 }, 213 { 214 name: "json", 215 args: args{ 216 format: "json", 217 }, 218 fields: fields{ 219 entry: zapcore.Entry{Level: zapcore.DebugLevel, Message: "json msg"}, 220 fields: []zap.Field{}, 221 }, 222 // like: 0001/01/01 00:00:00.000000 +0000 DEBUG console msg 223 wantOutput: regexp.MustCompile(`\{.*"level":"DEBUG".*"msg":"json msg".*\}`), 224 foundCnt: 1, 225 }, 226 } 227 for _, tt := range tests { 228 t.Run(tt.name, func(t *testing.T) { 229 got := getLoggerEncoder(tt.args.format) 230 require.NotNil(t, got) 231 buf, err := got.EncodeEntry(tt.fields.entry, tt.fields.fields) 232 require.Nil(t, err) 233 t.Logf("encode result: %s", buf.String()) 234 found := tt.wantOutput.FindAll(buf.Bytes(), -1) 235 t.Logf("found: %s", found) 236 require.Equal(t, tt.foundCnt, len(found)) 237 }) 238 } 239 } 240 241 func TestSetupMOLogger_panicDir(t *testing.T) { 242 type args struct { 243 conf *LogConfig 244 } 245 tests := []struct { 246 name string 247 args args 248 }{ 249 { 250 name: "normal", 251 args: args{conf: &LogConfig{ 252 Level: zapcore.DebugLevel.String(), 253 Format: "json", 254 Filename: t.TempDir(), 255 MaxSize: 512, 256 MaxDays: 0, 257 MaxBackups: 0, 258 259 DisableStore: true, 260 }}, 261 }, 262 } 263 for _, tt := range tests { 264 t.Run(tt.name, func(t *testing.T) { 265 defer func() { 266 if err := recover(); err != nil { 267 require.Equal(t, "log file can't be a directory", err) 268 } else { 269 t.Errorf("not receive panic") 270 } 271 }() 272 SetupMOLogger(tt.args.conf) 273 }) 274 } 275 }