github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/gin/logger_test.go (about) 1 // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 // Use of this source code is governed by a MIT style 3 // license that can be found in the LICENSE file. 4 5 package gin 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "github.com/hellobchain/newcryptosm/http" 12 "testing" 13 "time" 14 15 "github.com/stretchr/testify/assert" 16 ) 17 18 func init() { 19 SetMode(TestMode) 20 } 21 22 func TestLogger(t *testing.T) { 23 buffer := new(bytes.Buffer) 24 router := New() 25 router.Use(LoggerWithWriter(buffer)) 26 router.GET("/example", func(c *Context) {}) 27 router.POST("/example", func(c *Context) {}) 28 router.PUT("/example", func(c *Context) {}) 29 router.DELETE("/example", func(c *Context) {}) 30 router.PATCH("/example", func(c *Context) {}) 31 router.HEAD("/example", func(c *Context) {}) 32 router.OPTIONS("/example", func(c *Context) {}) 33 34 performRequest(router, "GET", "/example?a=100") 35 assert.Contains(t, buffer.String(), "200") 36 assert.Contains(t, buffer.String(), "GET") 37 assert.Contains(t, buffer.String(), "/example") 38 assert.Contains(t, buffer.String(), "a=100") 39 40 // I wrote these first (extending the above) but then realized they are more 41 // like integration tests because they test the whole logging process rather 42 // than individual functions. Im not sure where these should go. 43 buffer.Reset() 44 performRequest(router, "POST", "/example") 45 assert.Contains(t, buffer.String(), "200") 46 assert.Contains(t, buffer.String(), "POST") 47 assert.Contains(t, buffer.String(), "/example") 48 49 buffer.Reset() 50 performRequest(router, "PUT", "/example") 51 assert.Contains(t, buffer.String(), "200") 52 assert.Contains(t, buffer.String(), "PUT") 53 assert.Contains(t, buffer.String(), "/example") 54 55 buffer.Reset() 56 performRequest(router, "DELETE", "/example") 57 assert.Contains(t, buffer.String(), "200") 58 assert.Contains(t, buffer.String(), "DELETE") 59 assert.Contains(t, buffer.String(), "/example") 60 61 buffer.Reset() 62 performRequest(router, "PATCH", "/example") 63 assert.Contains(t, buffer.String(), "200") 64 assert.Contains(t, buffer.String(), "PATCH") 65 assert.Contains(t, buffer.String(), "/example") 66 67 buffer.Reset() 68 performRequest(router, "HEAD", "/example") 69 assert.Contains(t, buffer.String(), "200") 70 assert.Contains(t, buffer.String(), "HEAD") 71 assert.Contains(t, buffer.String(), "/example") 72 73 buffer.Reset() 74 performRequest(router, "OPTIONS", "/example") 75 assert.Contains(t, buffer.String(), "200") 76 assert.Contains(t, buffer.String(), "OPTIONS") 77 assert.Contains(t, buffer.String(), "/example") 78 79 buffer.Reset() 80 performRequest(router, "GET", "/notfound") 81 assert.Contains(t, buffer.String(), "404") 82 assert.Contains(t, buffer.String(), "GET") 83 assert.Contains(t, buffer.String(), "/notfound") 84 } 85 86 func TestLoggerWithConfig(t *testing.T) { 87 buffer := new(bytes.Buffer) 88 router := New() 89 router.Use(LoggerWithConfig(LoggerConfig{Output: buffer})) 90 router.GET("/example", func(c *Context) {}) 91 router.POST("/example", func(c *Context) {}) 92 router.PUT("/example", func(c *Context) {}) 93 router.DELETE("/example", func(c *Context) {}) 94 router.PATCH("/example", func(c *Context) {}) 95 router.HEAD("/example", func(c *Context) {}) 96 router.OPTIONS("/example", func(c *Context) {}) 97 98 performRequest(router, "GET", "/example?a=100") 99 assert.Contains(t, buffer.String(), "200") 100 assert.Contains(t, buffer.String(), "GET") 101 assert.Contains(t, buffer.String(), "/example") 102 assert.Contains(t, buffer.String(), "a=100") 103 104 // I wrote these first (extending the above) but then realized they are more 105 // like integration tests because they test the whole logging process rather 106 // than individual functions. Im not sure where these should go. 107 buffer.Reset() 108 performRequest(router, "POST", "/example") 109 assert.Contains(t, buffer.String(), "200") 110 assert.Contains(t, buffer.String(), "POST") 111 assert.Contains(t, buffer.String(), "/example") 112 113 buffer.Reset() 114 performRequest(router, "PUT", "/example") 115 assert.Contains(t, buffer.String(), "200") 116 assert.Contains(t, buffer.String(), "PUT") 117 assert.Contains(t, buffer.String(), "/example") 118 119 buffer.Reset() 120 performRequest(router, "DELETE", "/example") 121 assert.Contains(t, buffer.String(), "200") 122 assert.Contains(t, buffer.String(), "DELETE") 123 assert.Contains(t, buffer.String(), "/example") 124 125 buffer.Reset() 126 performRequest(router, "PATCH", "/example") 127 assert.Contains(t, buffer.String(), "200") 128 assert.Contains(t, buffer.String(), "PATCH") 129 assert.Contains(t, buffer.String(), "/example") 130 131 buffer.Reset() 132 performRequest(router, "HEAD", "/example") 133 assert.Contains(t, buffer.String(), "200") 134 assert.Contains(t, buffer.String(), "HEAD") 135 assert.Contains(t, buffer.String(), "/example") 136 137 buffer.Reset() 138 performRequest(router, "OPTIONS", "/example") 139 assert.Contains(t, buffer.String(), "200") 140 assert.Contains(t, buffer.String(), "OPTIONS") 141 assert.Contains(t, buffer.String(), "/example") 142 143 buffer.Reset() 144 performRequest(router, "GET", "/notfound") 145 assert.Contains(t, buffer.String(), "404") 146 assert.Contains(t, buffer.String(), "GET") 147 assert.Contains(t, buffer.String(), "/notfound") 148 } 149 150 func TestLoggerWithFormatter(t *testing.T) { 151 buffer := new(bytes.Buffer) 152 153 d := DefaultWriter 154 DefaultWriter = buffer 155 defer func() { 156 DefaultWriter = d 157 }() 158 159 router := New() 160 router.Use(LoggerWithFormatter(func(param LogFormatterParams) string { 161 return fmt.Sprintf("[FORMATTER TEST] %v | %3d | %13v | %15s | %-7s %#v\n%s", 162 param.TimeStamp.Format("2006/01/02 - 15:04:05"), 163 param.StatusCode, 164 param.Latency, 165 param.ClientIP, 166 param.Method, 167 param.Path, 168 param.ErrorMessage, 169 ) 170 })) 171 router.GET("/example", func(c *Context) {}) 172 performRequest(router, "GET", "/example?a=100") 173 174 // output test 175 assert.Contains(t, buffer.String(), "[FORMATTER TEST]") 176 assert.Contains(t, buffer.String(), "200") 177 assert.Contains(t, buffer.String(), "GET") 178 assert.Contains(t, buffer.String(), "/example") 179 assert.Contains(t, buffer.String(), "a=100") 180 } 181 182 func TestLoggerWithConfigFormatting(t *testing.T) { 183 var gotParam LogFormatterParams 184 var gotKeys map[string]interface{} 185 buffer := new(bytes.Buffer) 186 187 router := New() 188 router.engine.trustedCIDRs, _ = router.engine.prepareTrustedCIDRs() 189 190 router.Use(LoggerWithConfig(LoggerConfig{ 191 Output: buffer, 192 Formatter: func(param LogFormatterParams) string { 193 // for assert test 194 gotParam = param 195 196 return fmt.Sprintf("[FORMATTER TEST] %v | %3d | %13v | %15s | %-7s %s\n%s", 197 param.TimeStamp.Format("2006/01/02 - 15:04:05"), 198 param.StatusCode, 199 param.Latency, 200 param.ClientIP, 201 param.Method, 202 param.Path, 203 param.ErrorMessage, 204 ) 205 }, 206 })) 207 router.GET("/example", func(c *Context) { 208 // set dummy ClientIP 209 c.Request.Header.Set("X-Forwarded-For", "20.20.20.20") 210 gotKeys = c.Keys 211 }) 212 performRequest(router, "GET", "/example?a=100") 213 214 // output test 215 assert.Contains(t, buffer.String(), "[FORMATTER TEST]") 216 assert.Contains(t, buffer.String(), "200") 217 assert.Contains(t, buffer.String(), "GET") 218 assert.Contains(t, buffer.String(), "/example") 219 assert.Contains(t, buffer.String(), "a=100") 220 221 // LogFormatterParams test 222 assert.NotNil(t, gotParam.Request) 223 assert.NotEmpty(t, gotParam.TimeStamp) 224 assert.Equal(t, 200, gotParam.StatusCode) 225 assert.NotEmpty(t, gotParam.Latency) 226 assert.Equal(t, "20.20.20.20", gotParam.ClientIP) 227 assert.Equal(t, "GET", gotParam.Method) 228 assert.Equal(t, "/example?a=100", gotParam.Path) 229 assert.Empty(t, gotParam.ErrorMessage) 230 assert.Equal(t, gotKeys, gotParam.Keys) 231 232 } 233 234 func TestDefaultLogFormatter(t *testing.T) { 235 timeStamp := time.Unix(1544173902, 0).UTC() 236 237 termFalseParam := LogFormatterParams{ 238 TimeStamp: timeStamp, 239 StatusCode: 200, 240 Latency: time.Second * 5, 241 ClientIP: "20.20.20.20", 242 Method: "GET", 243 Path: "/", 244 ErrorMessage: "", 245 isTerm: false, 246 } 247 248 termTrueParam := LogFormatterParams{ 249 TimeStamp: timeStamp, 250 StatusCode: 200, 251 Latency: time.Second * 5, 252 ClientIP: "20.20.20.20", 253 Method: "GET", 254 Path: "/", 255 ErrorMessage: "", 256 isTerm: true, 257 } 258 termTrueLongDurationParam := LogFormatterParams{ 259 TimeStamp: timeStamp, 260 StatusCode: 200, 261 Latency: time.Millisecond * 9876543210, 262 ClientIP: "20.20.20.20", 263 Method: "GET", 264 Path: "/", 265 ErrorMessage: "", 266 isTerm: true, 267 } 268 269 termFalseLongDurationParam := LogFormatterParams{ 270 TimeStamp: timeStamp, 271 StatusCode: 200, 272 Latency: time.Millisecond * 9876543210, 273 ClientIP: "20.20.20.20", 274 Method: "GET", 275 Path: "/", 276 ErrorMessage: "", 277 isTerm: false, 278 } 279 280 assert.Equal(t, "[GIN] 2018/12/07 - 09:11:42 | 200 | 5s | 20.20.20.20 | GET \"/\"\n", defaultLogFormatter(termFalseParam)) 281 assert.Equal(t, "[GIN] 2018/12/07 - 09:11:42 | 200 | 2743h29m3s | 20.20.20.20 | GET \"/\"\n", defaultLogFormatter(termFalseLongDurationParam)) 282 283 assert.Equal(t, "[GIN] 2018/12/07 - 09:11:42 |\x1b[97;42m 200 \x1b[0m| 5s | 20.20.20.20 |\x1b[97;44m GET \x1b[0m \"/\"\n", defaultLogFormatter(termTrueParam)) 284 assert.Equal(t, "[GIN] 2018/12/07 - 09:11:42 |\x1b[97;42m 200 \x1b[0m| 2743h29m3s | 20.20.20.20 |\x1b[97;44m GET \x1b[0m \"/\"\n", defaultLogFormatter(termTrueLongDurationParam)) 285 286 } 287 288 func TestColorForMethod(t *testing.T) { 289 colorForMethod := func(method string) string { 290 p := LogFormatterParams{ 291 Method: method, 292 } 293 return p.MethodColor() 294 } 295 296 assert.Equal(t, blue, colorForMethod("GET"), "get should be blue") 297 assert.Equal(t, cyan, colorForMethod("POST"), "post should be cyan") 298 assert.Equal(t, yellow, colorForMethod("PUT"), "put should be yellow") 299 assert.Equal(t, red, colorForMethod("DELETE"), "delete should be red") 300 assert.Equal(t, green, colorForMethod("PATCH"), "patch should be green") 301 assert.Equal(t, magenta, colorForMethod("HEAD"), "head should be magenta") 302 assert.Equal(t, white, colorForMethod("OPTIONS"), "options should be white") 303 assert.Equal(t, reset, colorForMethod("TRACE"), "trace is not defined and should be the reset color") 304 } 305 306 func TestColorForStatus(t *testing.T) { 307 colorForStatus := func(code int) string { 308 p := LogFormatterParams{ 309 StatusCode: code, 310 } 311 return p.StatusCodeColor() 312 } 313 314 assert.Equal(t, green, colorForStatus(http.StatusOK), "2xx should be green") 315 assert.Equal(t, white, colorForStatus(http.StatusMovedPermanently), "3xx should be white") 316 assert.Equal(t, yellow, colorForStatus(http.StatusNotFound), "4xx should be yellow") 317 assert.Equal(t, red, colorForStatus(2), "other things should be red") 318 } 319 320 func TestResetColor(t *testing.T) { 321 p := LogFormatterParams{} 322 assert.Equal(t, string([]byte{27, 91, 48, 109}), p.ResetColor()) 323 } 324 325 func TestIsOutputColor(t *testing.T) { 326 // test with isTerm flag true. 327 p := LogFormatterParams{ 328 isTerm: true, 329 } 330 331 consoleColorMode = autoColor 332 assert.Equal(t, true, p.IsOutputColor()) 333 334 ForceConsoleColor() 335 assert.Equal(t, true, p.IsOutputColor()) 336 337 DisableConsoleColor() 338 assert.Equal(t, false, p.IsOutputColor()) 339 340 // test with isTerm flag false. 341 p = LogFormatterParams{ 342 isTerm: false, 343 } 344 345 consoleColorMode = autoColor 346 assert.Equal(t, false, p.IsOutputColor()) 347 348 ForceConsoleColor() 349 assert.Equal(t, true, p.IsOutputColor()) 350 351 DisableConsoleColor() 352 assert.Equal(t, false, p.IsOutputColor()) 353 354 // reset console color mode. 355 consoleColorMode = autoColor 356 } 357 358 func TestErrorLogger(t *testing.T) { 359 router := New() 360 router.Use(ErrorLogger()) 361 router.GET("/error", func(c *Context) { 362 c.Error(errors.New("this is an error")) // nolint: errcheck 363 }) 364 router.GET("/abort", func(c *Context) { 365 c.AbortWithError(http.StatusUnauthorized, errors.New("no authorized")) // nolint: errcheck 366 }) 367 router.GET("/print", func(c *Context) { 368 c.Error(errors.New("this is an error")) // nolint: errcheck 369 c.String(http.StatusInternalServerError, "hola!") 370 }) 371 372 w := performRequest(router, "GET", "/error") 373 assert.Equal(t, http.StatusOK, w.Code) 374 assert.Equal(t, "{\"error\":\"this is an error\"}", w.Body.String()) 375 376 w = performRequest(router, "GET", "/abort") 377 assert.Equal(t, http.StatusUnauthorized, w.Code) 378 assert.Equal(t, "{\"error\":\"no authorized\"}", w.Body.String()) 379 380 w = performRequest(router, "GET", "/print") 381 assert.Equal(t, http.StatusInternalServerError, w.Code) 382 assert.Equal(t, "hola!{\"error\":\"this is an error\"}", w.Body.String()) 383 } 384 385 func TestLoggerWithWriterSkippingPaths(t *testing.T) { 386 buffer := new(bytes.Buffer) 387 router := New() 388 router.Use(LoggerWithWriter(buffer, "/skipped")) 389 router.GET("/logged", func(c *Context) {}) 390 router.GET("/skipped", func(c *Context) {}) 391 392 performRequest(router, "GET", "/logged") 393 assert.Contains(t, buffer.String(), "200") 394 395 buffer.Reset() 396 performRequest(router, "GET", "/skipped") 397 assert.Contains(t, buffer.String(), "") 398 } 399 400 func TestLoggerWithConfigSkippingPaths(t *testing.T) { 401 buffer := new(bytes.Buffer) 402 router := New() 403 router.Use(LoggerWithConfig(LoggerConfig{ 404 Output: buffer, 405 SkipPaths: []string{"/skipped"}, 406 })) 407 router.GET("/logged", func(c *Context) {}) 408 router.GET("/skipped", func(c *Context) {}) 409 410 performRequest(router, "GET", "/logged") 411 assert.Contains(t, buffer.String(), "200") 412 413 buffer.Reset() 414 performRequest(router, "GET", "/skipped") 415 assert.Contains(t, buffer.String(), "") 416 } 417 418 func TestDisableConsoleColor(t *testing.T) { 419 New() 420 assert.Equal(t, autoColor, consoleColorMode) 421 DisableConsoleColor() 422 assert.Equal(t, disableColor, consoleColorMode) 423 424 // reset console color mode. 425 consoleColorMode = autoColor 426 } 427 428 func TestForceConsoleColor(t *testing.T) { 429 New() 430 assert.Equal(t, autoColor, consoleColorMode) 431 ForceConsoleColor() 432 assert.Equal(t, forceColor, consoleColorMode) 433 434 // reset console color mode. 435 consoleColorMode = autoColor 436 }