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  }