package middleware import ( "fmt" "io" "net/http" "net/http/httptest" "testing" "time" "github.com/99designs/gqlgen/graphql" "github.com/gin-gonic/gin" "github.com/penglongli/gin-metrics/ginmetrics" "github.com/stretchr/testify/assert" "github.com/vektah/gqlparser/v2/ast" ) func TestUseMetrics(t *testing.T) { assert := assert.New(t) UseMetrics(gin.Default()) m := ginmetrics.GetMonitor().GetMetric(graphQLRequests) assert.NotNil(m, "%s not defined", graphQLRequests) assert.Equal(&ginmetrics.Metric{ Type: ginmetrics.Counter, Name: graphQLRequests, Description: "count all graphql requests.", Labels: nil, }, &ginmetrics.Metric{ Type: m.Type, Name: m.Name, Description: m.Description, Labels: m.Labels, }) m = ginmetrics.GetMonitor().GetMetric(graphQlOperations) assert.NotNil(m, "%s not defined", graphQlOperations) assert.Equal(&ginmetrics.Metric{ Type: ginmetrics.Counter, Name: graphQlOperations, Description: "count all graphql requests by name, operation and status.", Labels: []string{"name", "operation", "status"}, }, &ginmetrics.Metric{ Type: m.Type, Name: m.Name, Description: m.Description, Labels: m.Labels, }) m = ginmetrics.GetMonitor().GetMetric(graphQLSlowReQuests) assert.NotNil(m, "%s not defined", graphQLSlowReQuests) assert.Equal(&ginmetrics.Metric{ Type: ginmetrics.Counter, Name: graphQLSlowReQuests, Description: fmt.Sprintf("count all graphql slow requests by name, operation and status. max_lentency=%d sec.", maxLatencySeconds), Labels: []string{"name", "operation", "status"}, }, &ginmetrics.Metric{ Type: m.Type, Name: m.Name, Description: m.Description, Labels: m.Labels, }) m = ginmetrics.GetMonitor().GetMetric(graphQLResponseTime) assert.NotNil(m, "%s not defined", graphQLResponseTime) assert.Equal(&ginmetrics.Metric{ Type: ginmetrics.Histogram, Name: graphQLResponseTime, Description: "the time graphql took handle the request by name.", Labels: []string{"name"}, Buckets: []float64{0.1, 0.3, 1.2, 5, 10}, }, &ginmetrics.Metric{ Type: m.Type, Name: m.Name, Description: m.Description, Labels: m.Labels, Buckets: m.Buckets, }) } func TestHandleGraphQlMetrics(t *testing.T) { assert := assert.New(t) r := gin.Default() UseMetrics(r) r.POST("/graphql", func(c *gin.Context) { ctx := &graphql.OperationContext{ Operation: &ast.OperationDefinition{ Operation: "query", }, } resp := &graphql.Response{} now := time.Now() slowTime := now.Add(-6 * time.Second) // fake latency HandleGraphQlMetrics(ctx, resp, slowTime) c.String(http.StatusOK, http.StatusText(http.StatusOK)) }) ts := httptest.NewServer(r) defer ts.Close() req, err := http.NewRequest(http.MethodPost, ts.URL+"/graphql", http.NoBody) assert.NoError(err) resp, err := http.DefaultClient.Do(req) assert.NoError(err) respBody, err := io.ReadAll(resp.Body) assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) assert.Equal(http.StatusText(http.StatusOK), string(respBody)) req, err = http.NewRequest(http.MethodGet, ts.URL+"/metrics", http.NoBody) assert.NoError(err) resp, err = http.DefaultClient.Do(req) assert.NoError(err) respBody, err = io.ReadAll(resp.Body) assert.NoError(err) body := string(respBody) for _, name := range []string{graphQLRequests, graphQlOperations, graphQLSlowReQuests, graphQLResponseTime} { assert.Contains(body, name, "metric: %s not found in call to /metrics", name) } }