Provide POST endpoint for query+query_range (#3322)

This PR fixes #3072 by providing POST endpoints for `query` and `query_range`.
POST request must be made with `Content-Type: application/x-www-form-urlencoded` header.
This commit is contained in:
Alexey Miroshkin 2017-11-11 01:53:48 +01:00 committed by Tobias Schmidt
parent 8022fc1aa3
commit 8c681f4a6c
2 changed files with 44 additions and 22 deletions

View File

@ -153,7 +153,9 @@ func (api *API) Register(r *route.Router) {
r.Options("/*path", instr("options", api.options))
r.Get("/query", instr("query", api.query))
r.Post("/query", instr("query", api.query))
r.Get("/query_range", instr("query_range", api.queryRange))
r.Post("/query_range", instr("query_range", api.queryRange))
r.Get("/label/:name/values", instr("label_values", api.labelValues))

View File

@ -24,6 +24,7 @@ import (
"net/http/httptest"
"net/url"
"reflect"
"strings"
"testing"
"time"
@ -450,33 +451,52 @@ func TestEndpoints(t *testing.T) {
},
}
for _, test := range tests {
// Build a context with the correct request params.
ctx := context.Background()
for p, v := range test.params {
ctx = route.WithParam(ctx, p, v)
methods := func(f apiFunc) []string {
fp := reflect.ValueOf(f).Pointer()
if fp == reflect.ValueOf(api.query).Pointer() || fp == reflect.ValueOf(api.queryRange).Pointer() {
return []string{http.MethodGet, http.MethodPost}
}
t.Logf("run query %q", test.query.Encode())
return []string{http.MethodGet}
}
req, err := http.NewRequest("ANY", fmt.Sprintf("http://example.com?%s", test.query.Encode()), nil)
if err != nil {
t.Fatal(err)
request := func(m string, q url.Values) (*http.Request, error) {
if m == http.MethodPost {
r, err := http.NewRequest(m, "http://example.com", strings.NewReader(q.Encode()))
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return r, err
}
resp, apiErr := test.endpoint(req.WithContext(ctx))
if apiErr != nil {
if test.errType == errorNone {
t.Fatalf("Unexpected error: %s", apiErr)
return http.NewRequest(m, fmt.Sprintf("http://example.com?%s", q.Encode()), nil)
}
for _, test := range tests {
for _, method := range methods(test.endpoint) {
// Build a context with the correct request params.
ctx := context.Background()
for p, v := range test.params {
ctx = route.WithParam(ctx, p, v)
}
if test.errType != apiErr.typ {
t.Fatalf("Expected error of type %q but got type %q", test.errType, apiErr.typ)
t.Logf("run %s\t%q", method, test.query.Encode())
req, err := request(method, test.query)
if err != nil {
t.Fatal(err)
}
resp, apiErr := test.endpoint(req.WithContext(ctx))
if apiErr != nil {
if test.errType == errorNone {
t.Fatalf("Unexpected error: %s", apiErr)
}
if test.errType != apiErr.typ {
t.Fatalf("Expected error of type %q but got type %q", test.errType, apiErr.typ)
}
continue
}
if apiErr == nil && test.errType != errorNone {
t.Fatalf("Expected error of type %q but got none", test.errType)
}
if !reflect.DeepEqual(resp, test.response) {
t.Fatalf("Response does not match, expected:\n%+v\ngot:\n%+v", test.response, resp)
}
continue
}
if apiErr == nil && test.errType != errorNone {
t.Fatalf("Expected error of type %q but got none", test.errType)
}
if !reflect.DeepEqual(resp, test.response) {
t.Fatalf("Response does not match, expected:\n%+v\ngot:\n%+v", test.response, resp)
}
}
}