github.com/99designs/gqlgen@v0.17.45/graphql/handler/apollotracing/tracer_test.go (about) 1 package apollotracing_test 2 3 import ( 4 "encoding/json" 5 "io" 6 "net/http" 7 "net/http/httptest" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 "github.com/vektah/gqlparser/v2/ast" 15 "github.com/vektah/gqlparser/v2/gqlerror" 16 17 "github.com/99designs/gqlgen/graphql" 18 "github.com/99designs/gqlgen/graphql/handler/apollotracing" 19 "github.com/99designs/gqlgen/graphql/handler/extension" 20 "github.com/99designs/gqlgen/graphql/handler/lru" 21 "github.com/99designs/gqlgen/graphql/handler/testserver" 22 "github.com/99designs/gqlgen/graphql/handler/transport" 23 ) 24 25 type alwaysError struct{} 26 27 func (a *alwaysError) Read(p []byte) (int, error) { 28 return 0, io.ErrUnexpectedEOF 29 } 30 31 func TestApolloTracing(t *testing.T) { 32 now := time.Unix(0, 0) 33 34 graphql.Now = func() time.Time { 35 defer func() { 36 now = now.Add(100 * time.Nanosecond) 37 }() 38 return now 39 } 40 41 h := testserver.New() 42 h.AddTransport(transport.POST{}) 43 h.Use(apollotracing.Tracer{}) 44 45 resp := doRequest(h, http.MethodPost, "/graphql", `{"query":"{ name }"}`) 46 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 47 var respData struct { 48 Extensions struct { 49 Tracing apollotracing.TracingExtension `json:"tracing"` 50 } `json:"extensions"` 51 } 52 require.NoError(t, json.Unmarshal(resp.Body.Bytes(), &respData)) 53 54 tracing := &respData.Extensions.Tracing 55 56 require.EqualValues(t, 1, tracing.Version) 57 58 require.Zero(t, tracing.StartTime.UnixNano()) 59 require.EqualValues(t, 900, tracing.EndTime.UnixNano()) 60 require.EqualValues(t, 900, tracing.Duration) 61 62 require.EqualValues(t, 300, tracing.Parsing.StartOffset) 63 require.EqualValues(t, 100, tracing.Parsing.Duration) 64 65 require.EqualValues(t, 500, tracing.Validation.StartOffset) 66 require.EqualValues(t, 100, tracing.Validation.Duration) 67 68 require.EqualValues(t, 700, tracing.Execution.Resolvers[0].StartOffset) 69 require.EqualValues(t, 100, tracing.Execution.Resolvers[0].Duration) 70 require.EqualValues(t, ast.Path{ast.PathName("name")}, tracing.Execution.Resolvers[0].Path) 71 require.Equal(t, "Query", tracing.Execution.Resolvers[0].ParentType) 72 require.Equal(t, "name", tracing.Execution.Resolvers[0].FieldName) 73 require.Equal(t, "String!", tracing.Execution.Resolvers[0].ReturnType) 74 } 75 76 func TestApolloTracing_withFail(t *testing.T) { 77 now := time.Unix(0, 0) 78 79 graphql.Now = func() time.Time { 80 defer func() { 81 now = now.Add(100 * time.Nanosecond) 82 }() 83 return now 84 } 85 86 h := testserver.New() 87 h.AddTransport(transport.POST{}) 88 h.Use(extension.AutomaticPersistedQuery{Cache: lru.New(100)}) 89 h.Use(apollotracing.Tracer{}) 90 91 resp := doRequest(h, http.MethodPost, "/graphql", `{"operationName":"A","extensions":{"persistedQuery":{"version":1,"sha256Hash":"338bbc16ac780daf81845339fbf0342061c1e9d2b702c96d3958a13a557083a6"}}}`) 92 assert.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) 93 b := resp.Body.Bytes() 94 t.Log(string(b)) 95 var respData struct { 96 Errors gqlerror.List 97 } 98 require.NoError(t, json.Unmarshal(b, &respData)) 99 require.Len(t, respData.Errors, 1) 100 require.Equal(t, "PersistedQueryNotFound", respData.Errors[0].Message) 101 } 102 103 func TestApolloTracing_withUnexpectedEOF(t *testing.T) { 104 h := testserver.New() 105 h.AddTransport(transport.POST{}) 106 h.Use(apollotracing.Tracer{}) 107 108 resp := doRequestWithReader(h, http.MethodPost, "/graphql", &alwaysError{}) 109 assert.Equal(t, http.StatusOK, resp.Code) 110 } 111 112 func doRequest(handler http.Handler, method, target, body string) *httptest.ResponseRecorder { 113 return doRequestWithReader(handler, method, target, strings.NewReader(body)) 114 } 115 116 func doRequestWithReader(handler http.Handler, method string, target string, 117 reader io.Reader) *httptest.ResponseRecorder { 118 r := httptest.NewRequest(method, target, reader) 119 r.Header.Set("Content-Type", "application/json") 120 w := httptest.NewRecorder() 121 122 handler.ServeHTTP(w, r) 123 return w 124 }