diff --git a/web/api/v1/api_test.go b/web/api/v1/api_test.go index df4114e25..ba6a99e87 100644 --- a/web/api/v1/api_test.go +++ b/web/api/v1/api_test.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "io/ioutil" + "math" "net/http" "net/http/httptest" "net/url" @@ -854,6 +855,107 @@ func TestOptionsMethod(t *testing.T) { } } +func TestRespond(t *testing.T) { + cases := []struct { + response interface{} + expected string + }{ + { + response: &queryData{ + ResultType: promql.ValueTypeMatrix, + Result: promql.Matrix{ + promql.Series{ + Points: []promql.Point{{V: 1, T: 1000}}, + Metric: labels.FromStrings("__name__", "foo"), + }, + }, + }, + expected: `{"status":"success","data":{"resultType":"matrix","result":[{"metric":{"__name__":"foo"},"values":[[1,"1"]]}]}}`, + }, + { + response: promql.Point{V: 0, T: 0}, + expected: `{"status":"success","data":[0,"0"]}`, + }, + { + response: promql.Point{V: 20, T: 1}, + expected: `{"status":"success","data":[0.001,"20"]}`, + }, + { + response: promql.Point{V: 20, T: 10}, + expected: `{"status":"success","data":[0.01,"20"]}`, + }, + { + response: promql.Point{V: 20, T: 100}, + expected: `{"status":"success","data":[0.1,"20"]}`, + }, + { + response: promql.Point{V: 20, T: 1001}, + expected: `{"status":"success","data":[1.001,"20"]}`, + }, + { + response: promql.Point{V: 20, T: 1010}, + expected: `{"status":"success","data":[1.01,"20"]}`, + }, + { + response: promql.Point{V: 20, T: 1100}, + expected: `{"status":"success","data":[1.1,"20"]}`, + }, + { + response: promql.Point{V: 20, T: 12345678123456555}, + expected: `{"status":"success","data":[12345678123456.557,"20"]}`, + }, + { + response: promql.Point{V: 20, T: -1}, + expected: `{"status":"success","data":[-0.001,"20"]}`, + }, + { + response: promql.Point{V: math.NaN(), T: 0}, + expected: `{"status":"success","data":[0,"NaN"]}`, + }, + { + response: promql.Point{V: math.Inf(1), T: 0}, + expected: `{"status":"success","data":[0,"+Inf"]}`, + }, + { + response: promql.Point{V: math.Inf(-1), T: 0}, + expected: `{"status":"success","data":[0,"-Inf"]}`, + }, + { + response: promql.Point{V: 1.2345678e6, T: 0}, + expected: `{"status":"success","data":[0,"1234567.8"]}`, + }, + { + response: promql.Point{V: 1.2345678e-6, T: 0}, + expected: `{"status":"success","data":[0,"0.0000012345678"]}`, + }, + { + response: promql.Point{V: 1.2345678e-67, T: 0}, + expected: `{"status":"success","data":[0,"1.2345678e-67"]}`, + }, + } + + for _, c := range cases { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + respond(w, c.response) + })) + defer s.Close() + + resp, err := http.Get(s.URL) + if err != nil { + t.Fatalf("Error on test request: %s", err) + } + body, err := ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + t.Fatalf("Error reading response body: %s", err) + } + + if string(body) != c.expected { + t.Fatalf("Expected response \n%v\n but got \n%v\n", c.expected, string(body)) + } + } +} + // This is a global to avoid the benchmark being optimized away. var testResponseWriter = httptest.ResponseRecorder{} @@ -872,6 +974,7 @@ func BenchmarkRespond(b *testing.B) { }, }, } + b.ResetTimer() for n := 0; n < b.N; n++ { respond(&testResponseWriter, response) }