func TestAPIs(t *testing.T) { testTime := time.Now() client := &apiTestClient{T: t} queryApi := &httpQueryAPI{ client: client, } doQuery := func(q string, ts time.Time) func() (interface{}, error) { return func() (interface{}, error) { return queryApi.Query(context.Background(), q, ts) } } doQueryRange := func(q string, rng Range) func() (interface{}, error) { return func() (interface{}, error) { return queryApi.QueryRange(context.Background(), q, rng) } } queryTests := []apiTest{ { do: doQuery("2", testTime), inRes: &queryResult{ Type: model.ValScalar, Result: &model.Scalar{ Value: 2, Timestamp: model.TimeFromUnix(testTime.Unix()), }, }, reqMethod: "GET", reqPath: "/api/v1/query", reqParam: url.Values{ "query": []string{"2"}, "time": []string{testTime.Format(time.RFC3339Nano)}, }, res: &model.Scalar{ Value: 2, Timestamp: model.TimeFromUnix(testTime.Unix()), }, }, { do: doQuery("2", testTime), inErr: fmt.Errorf("some error"), reqMethod: "GET", reqPath: "/api/v1/query", reqParam: url.Values{ "query": []string{"2"}, "time": []string{testTime.Format(time.RFC3339Nano)}, }, err: fmt.Errorf("some error"), }, { do: doQueryRange("2", Range{ Start: testTime.Add(-time.Minute), End: testTime, Step: time.Minute, }), inErr: fmt.Errorf("some error"), reqMethod: "GET", reqPath: "/api/v1/query_range", reqParam: url.Values{ "query": []string{"2"}, "start": []string{testTime.Add(-time.Minute).Format(time.RFC3339Nano)}, "end": []string{testTime.Format(time.RFC3339Nano)}, "step": []string{time.Minute.String()}, }, err: fmt.Errorf("some error"), }, } var tests []apiTest tests = append(tests, queryTests...) for _, test := range tests { client.curTest = test res, err := test.do() if test.err != nil { if err == nil { t.Errorf("expected error %q but got none", test.err) continue } if err.Error() != test.err.Error() { t.Errorf("unexpected error: want %s, got %s", test.err, err) } continue } if err != nil { t.Errorf("unexpected error: %s", err) continue } if !reflect.DeepEqual(res, test.res) { t.Errorf("unexpected result: want %v, got %v", test.res, res) } } }
"github.com/prometheus/common/model" "github.com/prometheus/common/route" "github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/storage/local" ) // This is a bit annoying. On one hand, we have to choose a current timestamp // because the storage doesn't have a mocked-out time yet and would otherwise // immediately throw away "old" samples. On the other hand, we have to make // sure that the float value survives the parsing and re-formatting in the // query layer precisely without any change. Thus we round to seconds and then // add known-good digits after the decimal point which behave well in // parsing/re-formatting. var testTimestamp = model.TimeFromUnix(time.Now().Round(time.Second).Unix()).Add(124 * time.Millisecond) func testNow() model.Time { return testTimestamp } func TestQuery(t *testing.T) { scenarios := []struct { // URL query string. queryStr string // Expected HTTP response status code. status int // Regex to match against response body. bodyRe string }{ {