github.com/thiagoyeds/go-cloud@v0.26.0/server/requestlog/requestlog_test.go (about) 1 // Copyright 2018 The Go Cloud Development Kit Authors 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 // https://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 requestlog 16 17 import ( 18 "context" 19 "fmt" 20 "io" 21 "net" 22 "net/http" 23 "net/http/httptest" 24 "strings" 25 "testing" 26 27 "go.opencensus.io/trace" 28 ) 29 30 func TestHandler(t *testing.T) { 31 const requestMsg = "Hello, World!" 32 const responseMsg = "I see you." 33 const userAgent = "Request Log Test UA" 34 const referer = "http://www.example.com/" 35 r, err := http.NewRequest("POST", "http://localhost/foo", strings.NewReader(requestMsg)) 36 if err != nil { 37 t.Fatal("NewRequest:", err) 38 } 39 r.Header.Set("User-Agent", userAgent) 40 r.Header.Set("Referer", referer) 41 requestHdrSize := len(fmt.Sprintf("User-Agent: %s\r\nReferer: %s\r\nContent-Length: %v\r\n", userAgent, referer, len(requestMsg))) 42 responseHdrSize := len(fmt.Sprintf("Content-Length: %v\r\n", len(responseMsg))) 43 ent, spanCtx, err := roundTrip(r, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 44 w.Header().Set("Content-Length", fmt.Sprint(len(responseMsg))) 45 w.WriteHeader(http.StatusOK) 46 io.WriteString(w, responseMsg) 47 })) 48 if err != nil { 49 t.Fatal("Could not get entry:", err) 50 } 51 if want := "test-baggage"; ent.Request.Context().Value("baggage") != want { 52 t.Errorf("Request Context Value = %s; want %s", ent.Request.Context().Value("baggage"), want) 53 } 54 if want := "/foo"; ent.Request.URL.Path != want { 55 t.Errorf("Request Context Value = %s; want %s", ent.Request.Context().Value("baggage"), want) 56 } 57 if want := "POST"; ent.RequestMethod != want { 58 t.Errorf("RequestMethod = %q; want %q", ent.RequestMethod, want) 59 } 60 if want := "/foo"; ent.RequestURL != want { 61 t.Errorf("RequestURL = %q; want %q", ent.RequestURL, want) 62 } 63 if ent.RequestHeaderSize < int64(requestHdrSize) { 64 t.Errorf("RequestHeaderSize = %d; want >=%d", ent.RequestHeaderSize, requestHdrSize) 65 } 66 if ent.RequestBodySize != int64(len(requestMsg)) { 67 t.Errorf("RequestBodySize = %d; want %d", ent.RequestBodySize, len(requestMsg)) 68 } 69 if ent.UserAgent != userAgent { 70 t.Errorf("UserAgent = %q; want %q", ent.UserAgent, userAgent) 71 } 72 if ent.Referer != referer { 73 t.Errorf("Referer = %q; want %q", ent.Referer, referer) 74 } 75 if want := "HTTP/1.1"; ent.Proto != want { 76 t.Errorf("Proto = %q; want %q", ent.Proto, want) 77 } 78 if ent.Status != http.StatusOK { 79 t.Errorf("Status = %d; want %d", ent.Status, http.StatusOK) 80 } 81 if ent.ResponseHeaderSize < int64(responseHdrSize) { 82 t.Errorf("ResponseHeaderSize = %d; want >=%d", ent.ResponseHeaderSize, responseHdrSize) 83 } 84 if ent.ResponseBodySize != int64(len(responseMsg)) { 85 t.Errorf("ResponseBodySize = %d; want %d", ent.ResponseBodySize, len(responseMsg)) 86 } 87 if ent.TraceID != spanCtx.TraceID { 88 t.Errorf("TraceID = %v; want %v", ent.TraceID, spanCtx.TraceID) 89 } 90 if ent.SpanID != spanCtx.SpanID { 91 t.Errorf("SpanID = %v; want %v", ent.SpanID, spanCtx.SpanID) 92 } 93 } 94 95 type testSpanHandler struct { 96 h http.Handler 97 spanCtx *trace.SpanContext 98 } 99 100 func (sh *testSpanHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 101 ctx, span := trace.StartSpan(r.Context(), "test") 102 defer span.End() 103 r = r.WithContext(ctx) 104 sc := trace.FromContext(ctx).SpanContext() 105 sh.spanCtx = &sc 106 sh.h.ServeHTTP(w, r) 107 } 108 109 func roundTrip(r *http.Request, h http.Handler) (*Entry, *trace.SpanContext, error) { 110 capture := new(captureLogger) 111 hh := NewHandler(capture, h) 112 handler := &testSpanHandler{h: hh} 113 s := httptest.NewUnstartedServer(handler) 114 s.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { 115 ctx = context.WithValue(ctx, "baggage", "test-baggage") 116 return ctx 117 } 118 s.Start() 119 defer s.Close() 120 r.URL.Host = s.URL[len("http://"):] 121 resp, err := http.DefaultClient.Do(r) 122 if err != nil { 123 return nil, nil, err 124 } 125 resp.Body.Close() 126 return &capture.ent, handler.spanCtx, nil 127 } 128 129 type captureLogger struct { 130 ent Entry 131 } 132 133 func (cl *captureLogger) Log(ent *Entry) { 134 cl.ent = *ent 135 }