...

Source file src/github.com/rs/zerolog/hlog/hlog_test.go

Documentation: github.com/rs/zerolog/hlog

     1  //go:build go1.7
     2  // +build go1.7
     3  
     4  package hlog
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"net/http"
    12  	"net/http/httptest"
    13  	"net/url"
    14  	"reflect"
    15  	"testing"
    16  
    17  	"github.com/rs/xid"
    18  	"github.com/rs/zerolog"
    19  	"github.com/rs/zerolog/internal/cbor"
    20  )
    21  
    22  func decodeIfBinary(out *bytes.Buffer) string {
    23  	p := out.Bytes()
    24  	if len(p) == 0 || p[0] < 0x7F {
    25  		return out.String()
    26  	}
    27  	return cbor.DecodeObjectToStr(p) + "\n"
    28  }
    29  
    30  func TestNewHandler(t *testing.T) {
    31  	log := zerolog.New(nil).With().
    32  		Str("foo", "bar").
    33  		Logger()
    34  	lh := NewHandler(log)
    35  	h := lh(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    36  		l := FromRequest(r)
    37  		if !reflect.DeepEqual(*l, log) {
    38  			t.Fail()
    39  		}
    40  	}))
    41  	h.ServeHTTP(nil, &http.Request{})
    42  }
    43  
    44  func TestURLHandler(t *testing.T) {
    45  	out := &bytes.Buffer{}
    46  	r := &http.Request{
    47  		URL: &url.URL{Path: "/path", RawQuery: "foo=bar"},
    48  	}
    49  	h := URLHandler("url")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    50  		l := FromRequest(r)
    51  		l.Log().Msg("")
    52  	}))
    53  	h = NewHandler(zerolog.New(out))(h)
    54  	h.ServeHTTP(nil, r)
    55  	if want, got := `{"url":"/path?foo=bar"}`+"\n", decodeIfBinary(out); want != got {
    56  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
    57  	}
    58  }
    59  
    60  func TestMethodHandler(t *testing.T) {
    61  	out := &bytes.Buffer{}
    62  	r := &http.Request{
    63  		Method: "POST",
    64  	}
    65  	h := MethodHandler("method")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    66  		l := FromRequest(r)
    67  		l.Log().Msg("")
    68  	}))
    69  	h = NewHandler(zerolog.New(out))(h)
    70  	h.ServeHTTP(nil, r)
    71  	if want, got := `{"method":"POST"}`+"\n", decodeIfBinary(out); want != got {
    72  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
    73  	}
    74  }
    75  
    76  func TestRequestHandler(t *testing.T) {
    77  	out := &bytes.Buffer{}
    78  	r := &http.Request{
    79  		Method: "POST",
    80  		URL:    &url.URL{Path: "/path", RawQuery: "foo=bar"},
    81  	}
    82  	h := RequestHandler("request")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    83  		l := FromRequest(r)
    84  		l.Log().Msg("")
    85  	}))
    86  	h = NewHandler(zerolog.New(out))(h)
    87  	h.ServeHTTP(nil, r)
    88  	if want, got := `{"request":"POST /path?foo=bar"}`+"\n", decodeIfBinary(out); want != got {
    89  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
    90  	}
    91  }
    92  
    93  func TestRemoteAddrHandler(t *testing.T) {
    94  	out := &bytes.Buffer{}
    95  	r := &http.Request{
    96  		RemoteAddr: "1.2.3.4:1234",
    97  	}
    98  	h := RemoteAddrHandler("ip")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    99  		l := FromRequest(r)
   100  		l.Log().Msg("")
   101  	}))
   102  	h = NewHandler(zerolog.New(out))(h)
   103  	h.ServeHTTP(nil, r)
   104  	if want, got := `{"ip":"1.2.3.4:1234"}`+"\n", decodeIfBinary(out); want != got {
   105  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
   106  	}
   107  }
   108  
   109  func TestRemoteAddrHandlerIPv6(t *testing.T) {
   110  	out := &bytes.Buffer{}
   111  	r := &http.Request{
   112  		RemoteAddr: "[2001:db8:a0b:12f0::1]:1234",
   113  	}
   114  	h := RemoteAddrHandler("ip")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   115  		l := FromRequest(r)
   116  		l.Log().Msg("")
   117  	}))
   118  	h = NewHandler(zerolog.New(out))(h)
   119  	h.ServeHTTP(nil, r)
   120  	if want, got := `{"ip":"[2001:db8:a0b:12f0::1]:1234"}`+"\n", decodeIfBinary(out); want != got {
   121  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
   122  	}
   123  }
   124  
   125  func TestUserAgentHandler(t *testing.T) {
   126  	out := &bytes.Buffer{}
   127  	r := &http.Request{
   128  		Header: http.Header{
   129  			"User-Agent": []string{"some user agent string"},
   130  		},
   131  	}
   132  	h := UserAgentHandler("ua")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   133  		l := FromRequest(r)
   134  		l.Log().Msg("")
   135  	}))
   136  	h = NewHandler(zerolog.New(out))(h)
   137  	h.ServeHTTP(nil, r)
   138  	if want, got := `{"ua":"some user agent string"}`+"\n", decodeIfBinary(out); want != got {
   139  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
   140  	}
   141  }
   142  
   143  func TestRefererHandler(t *testing.T) {
   144  	out := &bytes.Buffer{}
   145  	r := &http.Request{
   146  		Header: http.Header{
   147  			"Referer": []string{"http://foo.com/bar"},
   148  		},
   149  	}
   150  	h := RefererHandler("referer")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   151  		l := FromRequest(r)
   152  		l.Log().Msg("")
   153  	}))
   154  	h = NewHandler(zerolog.New(out))(h)
   155  	h.ServeHTTP(nil, r)
   156  	if want, got := `{"referer":"http://foo.com/bar"}`+"\n", decodeIfBinary(out); want != got {
   157  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
   158  	}
   159  }
   160  
   161  func TestRequestIDHandler(t *testing.T) {
   162  	out := &bytes.Buffer{}
   163  	r := &http.Request{
   164  		Header: http.Header{
   165  			"Referer": []string{"http://foo.com/bar"},
   166  		},
   167  	}
   168  	h := RequestIDHandler("id", "Request-Id")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   169  		id, ok := IDFromRequest(r)
   170  		if !ok {
   171  			t.Fatal("Missing id in request")
   172  		}
   173  		if want, got := id.String(), w.Header().Get("Request-Id"); got != want {
   174  			t.Errorf("Invalid Request-Id header, got: %s, want: %s", got, want)
   175  		}
   176  		l := FromRequest(r)
   177  		l.Log().Msg("")
   178  		if want, got := fmt.Sprintf(`{"id":"%s"}`+"\n", id), decodeIfBinary(out); want != got {
   179  			t.Errorf("Invalid log output, got: %s, want: %s", got, want)
   180  		}
   181  	}))
   182  	h = NewHandler(zerolog.New(out))(h)
   183  	h.ServeHTTP(httptest.NewRecorder(), r)
   184  }
   185  
   186  func TestCustomHeaderHandler(t *testing.T) {
   187  	out := &bytes.Buffer{}
   188  	r := &http.Request{
   189  		Header: http.Header{
   190  			"X-Request-Id": []string{"514bbe5bb5251c92bd07a9846f4a1ab6"},
   191  		},
   192  	}
   193  	h := CustomHeaderHandler("reqID", "X-Request-Id")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   194  		l := FromRequest(r)
   195  		l.Log().Msg("")
   196  	}))
   197  	h = NewHandler(zerolog.New(out))(h)
   198  	h.ServeHTTP(nil, r)
   199  	if want, got := `{"reqID":"514bbe5bb5251c92bd07a9846f4a1ab6"}`+"\n", decodeIfBinary(out); want != got {
   200  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
   201  	}
   202  }
   203  
   204  func TestProtoHandler(t *testing.T) {
   205  	out := &bytes.Buffer{}
   206  	r := &http.Request{
   207  		Proto: "test",
   208  	}
   209  	h := ProtoHandler("proto")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   210  		l := FromRequest(r)
   211  		l.Log().Msg("")
   212  	}))
   213  	h = NewHandler(zerolog.New(out))(h)
   214  	h.ServeHTTP(nil, r)
   215  	if want, got := `{"proto":"test"}`+"\n", decodeIfBinary(out); want != got {
   216  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
   217  	}
   218  }
   219  
   220  func TestCombinedHandlers(t *testing.T) {
   221  	out := &bytes.Buffer{}
   222  	r := &http.Request{
   223  		Method: "POST",
   224  		URL:    &url.URL{Path: "/path", RawQuery: "foo=bar"},
   225  	}
   226  	h := MethodHandler("method")(RequestHandler("request")(URLHandler("url")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   227  		l := FromRequest(r)
   228  		l.Log().Msg("")
   229  	}))))
   230  	h = NewHandler(zerolog.New(out))(h)
   231  	h.ServeHTTP(nil, r)
   232  	if want, got := `{"method":"POST","request":"POST /path?foo=bar","url":"/path?foo=bar"}`+"\n", decodeIfBinary(out); want != got {
   233  		t.Errorf("Invalid log output, got: %s, want: %s", got, want)
   234  	}
   235  }
   236  
   237  func BenchmarkHandlers(b *testing.B) {
   238  	r := &http.Request{
   239  		Method: "POST",
   240  		URL:    &url.URL{Path: "/path", RawQuery: "foo=bar"},
   241  	}
   242  	h1 := URLHandler("url")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   243  		l := FromRequest(r)
   244  		l.Log().Msg("")
   245  	}))
   246  	h2 := MethodHandler("method")(RequestHandler("request")(h1))
   247  	handlers := map[string]http.Handler{
   248  		"Single":           NewHandler(zerolog.New(ioutil.Discard))(h1),
   249  		"Combined":         NewHandler(zerolog.New(ioutil.Discard))(h2),
   250  		"SingleDisabled":   NewHandler(zerolog.New(ioutil.Discard).Level(zerolog.Disabled))(h1),
   251  		"CombinedDisabled": NewHandler(zerolog.New(ioutil.Discard).Level(zerolog.Disabled))(h2),
   252  	}
   253  	for name := range handlers {
   254  		h := handlers[name]
   255  		b.Run(name, func(b *testing.B) {
   256  			for i := 0; i < b.N; i++ {
   257  				h.ServeHTTP(nil, r)
   258  			}
   259  		})
   260  	}
   261  }
   262  
   263  func BenchmarkDataRace(b *testing.B) {
   264  	log := zerolog.New(nil).With().
   265  		Str("foo", "bar").
   266  		Logger()
   267  	lh := NewHandler(log)
   268  	h := lh(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   269  		l := FromRequest(r)
   270  		l.UpdateContext(func(c zerolog.Context) zerolog.Context {
   271  			return c.Str("bar", "baz")
   272  		})
   273  		l.Log().Msg("")
   274  	}))
   275  
   276  	b.RunParallel(func(pb *testing.PB) {
   277  		for pb.Next() {
   278  			h.ServeHTTP(nil, &http.Request{})
   279  		}
   280  	})
   281  }
   282  
   283  func TestCtxWithID(t *testing.T) {
   284  	ctx := context.Background()
   285  
   286  	id, _ := xid.FromString(`c0umremcie6smuu506pg`)
   287  
   288  	want := context.Background()
   289  	want = context.WithValue(want, idKey{}, id)
   290  
   291  	if got := CtxWithID(ctx, id); !reflect.DeepEqual(got, want) {
   292  		t.Errorf("CtxWithID() = %v, want %v", got, want)
   293  	}
   294  }
   295  

View as plain text