func TestMiddleware_useSpanFromHeaders(t *testing.T) { ms := appdash.NewMemoryStore() c := appdash.NewLocalCollector(ms) req, _ := http.NewRequest("GET", "http://example.com/foo", nil) req.Header.Set("X-Req-Header", "a") spanID := appdash.SpanID{1, 2, 3} SetSpanIDHeader(req.Header, spanID) var setContextSpan appdash.SpanID mw := Middleware(c, &MiddlewareConfig{ RouteName: func(r *http.Request) string { return "r" }, CurrentUser: func(r *http.Request) string { return "u" }, SetContextSpan: func(r *http.Request, id appdash.SpanID) { setContextSpan = id }, }) w := httptest.NewRecorder() mw(w, req, func(http.ResponseWriter, *http.Request) {}) if setContextSpan != spanID { t.Errorf("set context span to %v, want %v", setContextSpan, spanID) } trace, err := ms.Trace(1) if err != nil { t.Fatal(err) } var e ServerEvent if err := appdash.UnmarshalEvent(trace.Span.Annotations, &e); err != nil { t.Fatal(err) } wantEvent := ServerEvent{ Request: RequestInfo{ Method: "GET", Proto: "HTTP/1.1", URI: "/foo", Host: "example.com", Headers: map[string]string{"X-Req-Header": "a"}, }, Response: ResponseInfo{ StatusCode: 200, Headers: map[string]string{"Span-Id": "0000000000000001/0000000000000002/0000000000000003"}, }, User: "******", Route: "r", } delete(e.Request.Headers, "Span-Id") e.ServerRecv = time.Time{} e.ServerSend = time.Time{} if !reflect.DeepEqual(e, wantEvent) { t.Errorf("got ServerEvent %+v, want %+v", e, wantEvent) } }
func TestMiddleware_createNewSpan(t *testing.T) { ms := appdash.NewMemoryStore() c := appdash.NewLocalCollector(ms) req, _ := http.NewRequest("GET", "http://example.com/foo", nil) var setContextSpan appdash.SpanID mw := Middleware(c, &MiddlewareConfig{ SetContextSpan: func(r *http.Request, id appdash.SpanID) { setContextSpan = id }, }) w := httptest.NewRecorder() mw(w, req, func(http.ResponseWriter, *http.Request) {}) if setContextSpan == (appdash.SpanID{0, 0, 0}) { t.Errorf("context span is zero, want it to be set") } trace, err := ms.Trace(setContextSpan.Trace) if err != nil { t.Fatal(err) } var e ServerEvent if err := appdash.UnmarshalEvent(trace.Span.Annotations, &e); err != nil { t.Fatal(err) } wantEvent := ServerEvent{ Request: RequestInfo{ Method: "GET", Proto: "HTTP/1.1", URI: "/foo", Host: "example.com", }, Response: ResponseInfo{ StatusCode: 200, Headers: map[string]string{"Span-Id": setContextSpan.String()}, }, } delete(e.Request.Headers, "Span-Id") e.ServerRecv = time.Time{} e.ServerSend = time.Time{} if !reflect.DeepEqual(e, wantEvent) { t.Errorf("got ServerEvent %+v, want %+v", e, wantEvent) } }
func TestServerEvent_unmarshal(t *testing.T) { m := map[string]string{ "": "/foo", "_schema:name": "", "Server.User": "******", "Server.Recv": "0001-01-01T00:00:00Z", "Server.Send": "0001-01-01T00:00:00Z", "Server.Request.Host": "example.com", "Server.Request.RemoteAddr": "", "Server.Request.ContentLength": "0", "Server.Request.Method": "GET", "Server.Request.URI": "/foo", "Server.Request.Proto": "HTTP/1.1", "Server.Response.Headers.Span-Id": "15409ac1437f45e4/118217713a143137", "Server.Response.ContentLength": "0", "Server.Response.StatusCode": "200", "Server.Route": "r", "_schema:HTTPServer": "", } var e ServerEvent if err := appdash.UnmarshalEvent(mapToAnnotations(m), &e); err != nil { t.Fatal(err) } want := ServerEvent{ Request: RequestInfo{ Host: "example.com", Method: "GET", URI: "/foo", Proto: "HTTP/1.1", }, Response: ResponseInfo{ Headers: map[string]string{"Span-Id": "15409ac1437f45e4/118217713a143137"}, StatusCode: 200, }, Route: "r", User: "******", } want.ServerRecv = want.ServerRecv.In(time.UTC) want.ServerSend = want.ServerSend.In(time.UTC) if !reflect.DeepEqual(e, want) { t.Errorf("got ServerEvent %+v, want %+v", e, want) } }
func TestTransport(t *testing.T) { ms := appdash.NewMemoryStore() rec := appdash.NewRecorder(appdash.SpanID{1, 2, 3}, appdash.NewLocalCollector(ms)) req, _ := http.NewRequest("GET", "http://example.com/foo", nil) req.Header.Set("X-Req-Header", "a") mt := &mockTransport{ resp: &http.Response{ StatusCode: 200, ContentLength: 123, Header: http.Header{"X-Resp-Header": []string{"b"}}, }, } transport := &Transport{ Recorder: rec, Transport: mt, } _, err := transport.RoundTrip(req) if err != nil { t.Fatal(err) } spanID, err := appdash.ParseSpanID(mt.req.Header.Get("Span-ID")) if err != nil { t.Fatal(err) } if want := (appdash.SpanID{1, spanID.Span, 2}); *spanID != want { t.Errorf("got Span-ID in header %+v, want %+v", *spanID, want) } trace, err := ms.Trace(1) if err != nil { t.Fatal(err) } var e ClientEvent if err := appdash.UnmarshalEvent(trace.Span.Annotations, &e); err != nil { t.Fatal(err) } wantEvent := ClientEvent{ Request: RequestInfo{ Method: "GET", Proto: "HTTP/1.1", URI: "/foo", Host: "example.com", Headers: map[string]string{"X-Req-Header": "a"}, }, Response: ResponseInfo{ StatusCode: 200, ContentLength: 123, Headers: map[string]string{"X-Resp-Header": "b"}, }, } delete(e.Request.Headers, "Span-Id") e.ClientSend = time.Time{} e.ClientRecv = time.Time{} if !reflect.DeepEqual(e, wantEvent) { t.Errorf("got ClientEvent %+v, want %+v", e, wantEvent) } }