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 }
125
View as plain text