From c76acbadd625c3d13ec6cd15a632738a3d9d9fcc Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Fri, 14 Jan 2022 09:47:08 +0100 Subject: [PATCH] Prometheus: add tests covering the prometheus-response to dataframes conversion (#43892) (#44023) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * prometheus: add tests covering prometheus_response to grafana_dataframes * fixed variable name * added comment * removed not-helping function call (cherry picked from commit 4a88b8f66c7f27f4e2099f7e8a1781b804ca10b2) Co-authored-by: GÑbor Farkas --- .../prometheus/json_to_dataframes_test.go | 122 ++++++++++++++++++ .../testdata/range_infinity.query.json | 8 ++ .../testdata/range_infinity.result.golden.txt | 22 ++++ .../testdata/range_infinity.result.json | 16 +++ .../testdata/range_missing.query.json | 8 ++ .../testdata/range_missing.result.golden.txt | 28 ++++ .../testdata/range_missing.result.json | 16 +++ .../prometheus/testdata/range_nan.query.json | 7 + .../testdata/range_nan.result.golden.txt | 22 ++++ .../prometheus/testdata/range_nan.result.json | 16 +++ .../testdata/range_simple.query.json | 7 + .../testdata/range_simple.result.golden.txt | 42 ++++++ .../testdata/range_simple.result.json | 34 +++++ pkg/tsdb/prometheus/time_series_query.go | 29 +++-- 14 files changed, 366 insertions(+), 11 deletions(-) create mode 100644 pkg/tsdb/prometheus/json_to_dataframes_test.go create mode 100644 pkg/tsdb/prometheus/testdata/range_infinity.query.json create mode 100644 pkg/tsdb/prometheus/testdata/range_infinity.result.golden.txt create mode 100644 pkg/tsdb/prometheus/testdata/range_infinity.result.json create mode 100644 pkg/tsdb/prometheus/testdata/range_missing.query.json create mode 100644 pkg/tsdb/prometheus/testdata/range_missing.result.golden.txt create mode 100644 pkg/tsdb/prometheus/testdata/range_missing.result.json create mode 100644 pkg/tsdb/prometheus/testdata/range_nan.query.json create mode 100644 pkg/tsdb/prometheus/testdata/range_nan.result.golden.txt create mode 100644 pkg/tsdb/prometheus/testdata/range_nan.result.json create mode 100644 pkg/tsdb/prometheus/testdata/range_simple.query.json create mode 100644 pkg/tsdb/prometheus/testdata/range_simple.result.golden.txt create mode 100644 pkg/tsdb/prometheus/testdata/range_simple.result.json diff --git a/pkg/tsdb/prometheus/json_to_dataframes_test.go b/pkg/tsdb/prometheus/json_to_dataframes_test.go new file mode 100644 index 00000000000..aaf782ec0ff --- /dev/null +++ b/pkg/tsdb/prometheus/json_to_dataframes_test.go @@ -0,0 +1,122 @@ +package prometheus + +import ( + "bytes" + "context" + "encoding/json" + "io" + "net/http" + "os" + "path/filepath" + "testing" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/experimental" + "github.com/prometheus/client_golang/api" + apiv1 "github.com/prometheus/client_golang/api/prometheus/v1" + "github.com/stretchr/testify/require" +) + +func TestMatrixResponses(t *testing.T) { + t.Run("parse a simple matrix response", func(t *testing.T) { + testScenario(t, "range_simple") + }) + + t.Run("parse a simple matrix response with value missing steps", func(t *testing.T) { + testScenario(t, "range_missing") + }) + + t.Run("parse a response with Infinity", func(t *testing.T) { + testScenario(t, "range_infinity") + }) + + t.Run("parse a response with NaN", func(t *testing.T) { + testScenario(t, "range_nan") + }) +} + +type mockedRoundTripper struct { + responseBytes []byte +} + +func (mockedRT *mockedRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewReader(mockedRT.responseBytes)), + }, nil +} + +func makeMockedApi(responseBytes []byte) (apiv1.API, error) { + roundTripper := mockedRoundTripper{responseBytes: responseBytes} + + cfg := api.Config{ + Address: "http://localhost:9999", + RoundTripper: &roundTripper, + } + + client, err := api.NewClient(cfg) + if err != nil { + return nil, err + } + + api := apiv1.NewAPI(client) + + return api, nil +} + +// we store the prometheus query data in a json file, here is some minimal code +// to be able to read it back. unfortunately we cannot use the PrometheusQuery +// struct here, because it has `time.time` and `time.duration` fields that +// cannot be unmarshalled from JSON automatically. +type storedPrometheusQuery struct { + RefId string + RangeQuery bool + Start int64 + End int64 + Step int64 + Expr string +} + +func loadStoredPrometheusQuery(t *testing.T, fileName string) PrometheusQuery { + bytes, err := os.ReadFile(fileName) + require.NoError(t, err) + + var query storedPrometheusQuery + + err = json.Unmarshal(bytes, &query) + require.NoError(t, err) + + return PrometheusQuery{ + RefId: query.RefId, + RangeQuery: query.RangeQuery, + Start: time.Unix(query.Start, 0), + End: time.Unix(query.End, 0), + Step: time.Second * time.Duration(query.Step), + Expr: query.Expr, + } +} + +// we run the mocked query, and extract the DataResponse. +// we assume and verify that there is exactly one DataResponse returned. +func testScenario(t *testing.T, name string) { + queryFileName := filepath.Join("testdata", name+".query.json") + responseFileName := filepath.Join("testdata", name+".result.json") + goldenFileName := filepath.Join("testdata", name+".result.golden.txt") + query := loadStoredPrometheusQuery(t, queryFileName) + responseBytes, err := os.ReadFile(responseFileName) + require.NoError(t, err) + + api, err := makeMockedApi(responseBytes) + require.NoError(t, err) + + result, err := runQueries(context.Background(), api, []*PrometheusQuery{&query}) + require.NoError(t, err) + require.Len(t, result.Responses, 1) + + dr, found := result.Responses["A"] + require.True(t, found) + require.NoError(t, dr.Error) + + err = experimental.CheckGoldenDataResponse(goldenFileName, &dr, true) + require.NoError(t, err) +} diff --git a/pkg/tsdb/prometheus/testdata/range_infinity.query.json b/pkg/tsdb/prometheus/testdata/range_infinity.query.json new file mode 100644 index 00000000000..76d612b6824 --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_infinity.query.json @@ -0,0 +1,8 @@ +{ + "RefId": "A", + "RangeQuery": true, + "Start": 1641889530, + "End": 1641889532, + "Step": 1, + "Expr": "1 / 0" +} diff --git a/pkg/tsdb/prometheus/testdata/range_infinity.result.golden.txt b/pkg/tsdb/prometheus/testdata/range_infinity.result.golden.txt new file mode 100644 index 00000000000..2aad902f0db --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_infinity.result.golden.txt @@ -0,0 +1,22 @@ +🌟 This was machine generated. Do not edit. 🌟 + +Frame[0] { + "custom": { + "resultType": "matrix" + } +} +Name: 1 / 0 +Dimensions: 2 Fields by 3 Rows ++-------------------------------+------------------+ +| Name: Time | Name: Value | +| Labels: | Labels: | +| Type: []time.Time | Type: []*float64 | ++-------------------------------+------------------+ +| 2022-01-11 08:25:30 +0000 UTC | +Inf | +| 2022-01-11 08:25:31 +0000 UTC | +Inf | +| 2022-01-11 08:25:32 +0000 UTC | +Inf | ++-------------------------------+------------------+ + + +====== TEST DATA RESPONSE (arrow base64) ====== +FRAME=QVJST1cxAAD/////KAIAABAAAAAAAAoADgAMAAsABAAKAAAAFAAAAAAAAAEDAAoADAAAAAgABAAKAAAACAAAAJgAAAADAAAAUAAAACgAAAAEAAAAbP7//wgAAAAMAAAAAAAAAAAAAAAFAAAAcmVmSWQAAACM/v//CAAAABAAAAAFAAAAMSAvIDAAAAAEAAAAbmFtZQAAAACw/v//CAAAACwAAAAiAAAAeyJjdXN0b20iOnsicmVzdWx0VHlwZSI6Im1hdHJpeCJ9fQAABAAAAG1ldGEAAAAAAgAAAOwAAAAYAAAAAAASABgAFAATABIADAAAAAgABAASAAAAFAAAAKAAAACgAAAAAAADAaAAAAADAAAAUAAAACwAAAAEAAAAOP///wgAAAAQAAAABQAAAFZhbHVlAAAABAAAAG5hbWUAAAAAXP///wgAAAAMAAAAAgAAAHt9AAAGAAAAbGFiZWxzAAB8////CAAAACgAAAAdAAAAeyJkaXNwbGF5TmFtZUZyb21EUyI6IjEgLyAwIn0AAAAGAAAAY29uZmlnAAAAAAAAiv///wAAAgAFAAAAVmFsdWUAEgAYABQAAAATAAwAAAAIAAQAEgAAABQAAABEAAAATAAAAAAAAApMAAAAAQAAAAwAAAAIAAwACAAEAAgAAAAIAAAAEAAAAAQAAABUaW1lAAAAAAQAAABuYW1lAAAAAAAAAAAAAAYACAAGAAYAAAAAAAMABAAAAFRpbWUAAAAAAAAAAP////+4AAAAFAAAAAAAAAAMABYAFAATAAwABAAMAAAAMAAAAAAAAAAUAAAAAAAAAwMACgAYAAwACAAEAAoAAAAUAAAAWAAAAAMAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAAAAAAAIAAAADAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAABEFRTUKckWAA6wT9QpyRYA2EqL1CnJFgAAAAAAAPB/AAAAAAAA8H8AAAAAAADwfxAAAAAMABQAEgAMAAgABAAMAAAAEAAAACwAAAA4AAAAAAADAAEAAAA4AgAAAAAAAMAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAACgAMAAAACAAEAAoAAAAIAAAAmAAAAAMAAABQAAAAKAAAAAQAAABs/v//CAAAAAwAAAAAAAAAAAAAAAUAAAByZWZJZAAAAIz+//8IAAAAEAAAAAUAAAAxIC8gMAAAAAQAAABuYW1lAAAAALD+//8IAAAALAAAACIAAAB7ImN1c3RvbSI6eyJyZXN1bHRUeXBlIjoibWF0cml4In19AAAEAAAAbWV0YQAAAAACAAAA7AAAABgAAAAAABIAGAAUABMAEgAMAAAACAAEABIAAAAUAAAAoAAAAKAAAAAAAAMBoAAAAAMAAABQAAAALAAAAAQAAAA4////CAAAABAAAAAFAAAAVmFsdWUAAAAEAAAAbmFtZQAAAABc////CAAAAAwAAAACAAAAe30AAAYAAABsYWJlbHMAAHz///8IAAAAKAAAAB0AAAB7ImRpc3BsYXlOYW1lRnJvbURTIjoiMSAvIDAifQAAAAYAAABjb25maWcAAAAAAACK////AAACAAUAAABWYWx1ZQASABgAFAAAABMADAAAAAgABAASAAAAFAAAAEQAAABMAAAAAAAACkwAAAABAAAADAAAAAgADAAIAAQACAAAAAgAAAAQAAAABAAAAFRpbWUAAAAABAAAAG5hbWUAAAAAAAAAAAAABgAIAAYABgAAAAAAAwAEAAAAVGltZQAAAABQAgAAQVJST1cx diff --git a/pkg/tsdb/prometheus/testdata/range_infinity.result.json b/pkg/tsdb/prometheus/testdata/range_infinity.result.json new file mode 100644 index 00000000000..7059de48f6f --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_infinity.result.json @@ -0,0 +1,16 @@ +{ + "status": "success", + "data": { + "resultType": "matrix", + "result": [ + { + "metric": {}, + "values": [ + [1641889530, "+Inf"], + [1641889531, "+Inf"], + [1641889532, "+Inf"] + ] + } + ] + } +} diff --git a/pkg/tsdb/prometheus/testdata/range_missing.query.json b/pkg/tsdb/prometheus/testdata/range_missing.query.json new file mode 100644 index 00000000000..3388e0d45b9 --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_missing.query.json @@ -0,0 +1,8 @@ +{ + "RefId": "A", + "RangeQuery": true, + "Start": 1641889530, + "End": 1641889538, + "Step": 1, + "Expr": "test1" +} diff --git a/pkg/tsdb/prometheus/testdata/range_missing.result.golden.txt b/pkg/tsdb/prometheus/testdata/range_missing.result.golden.txt new file mode 100644 index 00000000000..6de43e6a90f --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_missing.result.golden.txt @@ -0,0 +1,28 @@ +🌟 This was machine generated. Do not edit. 🌟 + +Frame[0] { + "custom": { + "resultType": "matrix" + } +} +Name: go_goroutines{job="prometheus"} +Dimensions: 2 Fields by 9 Rows ++-------------------------------+------------------------------------------------+ +| Name: Time | Name: Value | +| Labels: | Labels: __name__=go_goroutines, job=prometheus | +| Type: []time.Time | Type: []*float64 | ++-------------------------------+------------------------------------------------+ +| 2022-01-11 08:25:30 +0000 UTC | null | +| 2022-01-11 08:25:31 +0000 UTC | null | +| 2022-01-11 08:25:32 +0000 UTC | null | +| 2022-01-11 08:25:33 +0000 UTC | 21 | +| 2022-01-11 08:25:34 +0000 UTC | 32 | +| 2022-01-11 08:25:35 +0000 UTC | null | +| 2022-01-11 08:25:36 +0000 UTC | null | +| 2022-01-11 08:25:37 +0000 UTC | 43 | +| 0001-01-01 00:00:00 +0000 UTC | null | ++-------------------------------+------------------------------------------------+ + + +====== TEST DATA RESPONSE (arrow base64) ====== +FRAME=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 diff --git a/pkg/tsdb/prometheus/testdata/range_missing.result.json b/pkg/tsdb/prometheus/testdata/range_missing.result.json new file mode 100644 index 00000000000..9ace3676baf --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_missing.result.json @@ -0,0 +1,16 @@ +{ + "status": "success", + "data": { + "resultType": "matrix", + "result": [ + { + "metric": { "__name__": "go_goroutines", "job": "prometheus" }, + "values": [ + [1641889533, "21"], + [1641889534, "32"], + [1641889537, "43"] + ] + } + ] + } +} diff --git a/pkg/tsdb/prometheus/testdata/range_nan.query.json b/pkg/tsdb/prometheus/testdata/range_nan.query.json new file mode 100644 index 00000000000..6a5698600d2 --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_nan.query.json @@ -0,0 +1,7 @@ +{ + "RefId": "A", + "RangeQuery": true, + "Start": 1641889530, + "End": 1641889532, + "Step": 1 +} diff --git a/pkg/tsdb/prometheus/testdata/range_nan.result.golden.txt b/pkg/tsdb/prometheus/testdata/range_nan.result.golden.txt new file mode 100644 index 00000000000..f4d34e2a377 --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_nan.result.golden.txt @@ -0,0 +1,22 @@ +🌟 This was machine generated. Do not edit. 🌟 + +Frame[0] { + "custom": { + "resultType": "matrix" + } +} +Name: {handler="/api/v1/query_range", job="prometheus"} +Dimensions: 2 Fields by 3 Rows ++-------------------------------+-----------------------------------------------------+ +| Name: Time | Name: Value | +| Labels: | Labels: handler=/api/v1/query_range, job=prometheus | +| Type: []time.Time | Type: []*float64 | ++-------------------------------+-----------------------------------------------------+ +| 2022-01-11 08:25:30 +0000 UTC | null | +| 2022-01-11 08:25:31 +0000 UTC | null | +| 2022-01-11 08:25:32 +0000 UTC | null | ++-------------------------------+-----------------------------------------------------+ + + +====== TEST DATA RESPONSE (arrow base64) ====== +FRAME=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 diff --git a/pkg/tsdb/prometheus/testdata/range_nan.result.json b/pkg/tsdb/prometheus/testdata/range_nan.result.json new file mode 100644 index 00000000000..06517c9a488 --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_nan.result.json @@ -0,0 +1,16 @@ +{ + "status": "success", + "data": { + "resultType": "matrix", + "result": [ + { + "metric": { "handler": "/api/v1/query_range", "job": "prometheus" }, + "values": [ + [1641889530, "NaN"], + [1641889531, "NaN"], + [1641889532, "NaN"] + ] + } + ] + } +} diff --git a/pkg/tsdb/prometheus/testdata/range_simple.query.json b/pkg/tsdb/prometheus/testdata/range_simple.query.json new file mode 100644 index 00000000000..6a5698600d2 --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_simple.query.json @@ -0,0 +1,7 @@ +{ + "RefId": "A", + "RangeQuery": true, + "Start": 1641889530, + "End": 1641889532, + "Step": 1 +} diff --git a/pkg/tsdb/prometheus/testdata/range_simple.result.golden.txt b/pkg/tsdb/prometheus/testdata/range_simple.result.golden.txt new file mode 100644 index 00000000000..7866187f0e6 --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_simple.result.golden.txt @@ -0,0 +1,42 @@ +🌟 This was machine generated. Do not edit. 🌟 + +Frame[0] { + "custom": { + "resultType": "matrix" + } +} +Name: prometheus_http_requests_total{code="200", handler="/api/v1/query_range", job="prometheus"} +Dimensions: 2 Fields by 3 Rows ++-------------------------------+--------------------------------------------------------------------------------------------------------+ +| Name: Time | Name: Value | +| Labels: | Labels: __name__=prometheus_http_requests_total, code=200, handler=/api/v1/query_range, job=prometheus | +| Type: []time.Time | Type: []*float64 | ++-------------------------------+--------------------------------------------------------------------------------------------------------+ +| 2022-01-11 08:25:30 +0000 UTC | 21 | +| 2022-01-11 08:25:31 +0000 UTC | 32 | +| 2022-01-11 08:25:32 +0000 UTC | 43 | ++-------------------------------+--------------------------------------------------------------------------------------------------------+ + + + +Frame[1] { + "custom": { + "resultType": "matrix" + } +} +Name: prometheus_http_requests_total{code="400", handler="/api/v1/query_range", job="prometheus"} +Dimensions: 2 Fields by 3 Rows ++-------------------------------+--------------------------------------------------------------------------------------------------------+ +| Name: Time | Name: Value | +| Labels: | Labels: __name__=prometheus_http_requests_total, code=400, handler=/api/v1/query_range, job=prometheus | +| Type: []time.Time | Type: []*float64 | ++-------------------------------+--------------------------------------------------------------------------------------------------------+ +| 2022-01-11 08:25:30 +0000 UTC | 54 | +| 2022-01-11 08:25:31 +0000 UTC | 65 | +| 2022-01-11 08:25:32 +0000 UTC | 76 | ++-------------------------------+--------------------------------------------------------------------------------------------------------+ + + +====== TEST DATA RESPONSE (arrow base64) ====== +FRAME=QVJST1cxAAD/////QAMAABAAAAAAAAoADgAMAAsABAAKAAAAFAAAAAAAAAEDAAoADAAAAAgABAAKAAAACAAAAOwAAAADAAAApAAAACgAAAAEAAAAUP3//wgAAAAMAAAAAAAAAAAAAAAFAAAAcmVmSWQAAABw/f//CAAAAGQAAABbAAAAcHJvbWV0aGV1c19odHRwX3JlcXVlc3RzX3RvdGFse2NvZGU9IjIwMCIsIGhhbmRsZXI9Ii9hcGkvdjEvcXVlcnlfcmFuZ2UiLCBqb2I9InByb21ldGhldXMifQAEAAAAbmFtZQAAAADo/f//CAAAACwAAAAiAAAAeyJjdXN0b20iOnsicmVzdWx0VHlwZSI6Im1hdHJpeCJ9fQAABAAAAG1ldGEAAAAAAgAAALQBAAAYAAAAAAASABgAFAATABIADAAAAAgABAASAAAAFAAAAGgBAABoAQAAAAADAWgBAAADAAAAvAAAACwAAAAEAAAAcP7//wgAAAAQAAAABQAAAFZhbHVlAAAABAAAAG5hbWUAAAAAlP7//wgAAAB4AAAAbQAAAHsiX19uYW1lX18iOiJwcm9tZXRoZXVzX2h0dHBfcmVxdWVzdHNfdG90YWwiLCJjb2RlIjoiMjAwIiwiaGFuZGxlciI6Ii9hcGkvdjEvcXVlcnlfcmFuZ2UiLCJqb2IiOiJwcm9tZXRoZXVzIn0AAAAGAAAAbGFiZWxzAAAg////CAAAAIQAAAB5AAAAeyJkaXNwbGF5TmFtZUZyb21EUyI6InByb21ldGhldXNfaHR0cF9yZXF1ZXN0c190b3RhbHtjb2RlPVwiMjAwXCIsIGhhbmRsZXI9XCIvYXBpL3YxL3F1ZXJ5X3JhbmdlXCIsIGpvYj1cInByb21ldGhldXNcIn0ifQAAAAYAAABjb25maWcAAAAAAACK////AAACAAUAAABWYWx1ZQASABgAFAAAABMADAAAAAgABAASAAAAFAAAAEQAAABMAAAAAAAACkwAAAABAAAADAAAAAgADAAIAAQACAAAAAgAAAAQAAAABAAAAFRpbWUAAAAABAAAAG5hbWUAAAAAAAAAAAAABgAIAAYABgAAAAAAAwAEAAAAVGltZQAAAAD/////uAAAABQAAAAAAAAADAAWABQAEwAMAAQADAAAADAAAAAAAAAAFAAAAAAAAAMDAAoAGAAMAAgABAAKAAAAFAAAAFgAAAADAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAYAAAAAAAAAAAAAAACAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAARBUU1CnJFgAOsE/UKckWANhKi9QpyRYAAAAAAAA1QAAAAAAAAEBAAAAAAACARUAQAAAADAAUABIADAAIAAQADAAAABAAAAAsAAAAPAAAAAAAAwABAAAAUAMAAAAAAADAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAwAAAAIAAQACgAAAAgAAADsAAAAAwAAAKQAAAAoAAAABAAAAFD9//8IAAAADAAAAAAAAAAAAAAABQAAAHJlZklkAAAAcP3//wgAAABkAAAAWwAAAHByb21ldGhldXNfaHR0cF9yZXF1ZXN0c190b3RhbHtjb2RlPSIyMDAiLCBoYW5kbGVyPSIvYXBpL3YxL3F1ZXJ5X3JhbmdlIiwgam9iPSJwcm9tZXRoZXVzIn0ABAAAAG5hbWUAAAAA6P3//wgAAAAsAAAAIgAAAHsiY3VzdG9tIjp7InJlc3VsdFR5cGUiOiJtYXRyaXgifX0AAAQAAABtZXRhAAAAAAIAAAC0AQAAGAAAAAAAEgAYABQAEwASAAwAAAAIAAQAEgAAABQAAABoAQAAaAEAAAAAAwFoAQAAAwAAALwAAAAsAAAABAAAAHD+//8IAAAAEAAAAAUAAABWYWx1ZQAAAAQAAABuYW1lAAAAAJT+//8IAAAAeAAAAG0AAAB7Il9fbmFtZV9fIjoicHJvbWV0aGV1c19odHRwX3JlcXVlc3RzX3RvdGFsIiwiY29kZSI6IjIwMCIsImhhbmRsZXIiOiIvYXBpL3YxL3F1ZXJ5X3JhbmdlIiwiam9iIjoicHJvbWV0aGV1cyJ9AAAABgAAAGxhYmVscwAAIP///wgAAACEAAAAeQAAAHsiZGlzcGxheU5hbWVGcm9tRFMiOiJwcm9tZXRoZXVzX2h0dHBfcmVxdWVzdHNfdG90YWx7Y29kZT1cIjIwMFwiLCBoYW5kbGVyPVwiL2FwaS92MS9xdWVyeV9yYW5nZVwiLCBqb2I9XCJwcm9tZXRoZXVzXCJ9In0AAAAGAAAAY29uZmlnAAAAAAAAiv///wAAAgAFAAAAVmFsdWUAEgAYABQAAAATAAwAAAAIAAQAEgAAABQAAABEAAAATAAAAAAAAApMAAAAAQAAAAwAAAAIAAwACAAEAAgAAAAIAAAAEAAAAAQAAABUaW1lAAAAAAQAAABuYW1lAAAAAAAAAAAAAAYACAAGAAYAAAAAAAMABAAAAFRpbWUAAAAAcAMAAEFSUk9XMQ== +FRAME=QVJST1cxAAD/////QAMAABAAAAAAAAoADgAMAAsABAAKAAAAFAAAAAAAAAEDAAoADAAAAAgABAAKAAAACAAAAOwAAAADAAAApAAAACgAAAAEAAAAUP3//wgAAAAMAAAAAAAAAAAAAAAFAAAAcmVmSWQAAABw/f//CAAAAGQAAABbAAAAcHJvbWV0aGV1c19odHRwX3JlcXVlc3RzX3RvdGFse2NvZGU9IjQwMCIsIGhhbmRsZXI9Ii9hcGkvdjEvcXVlcnlfcmFuZ2UiLCBqb2I9InByb21ldGhldXMifQAEAAAAbmFtZQAAAADo/f//CAAAACwAAAAiAAAAeyJjdXN0b20iOnsicmVzdWx0VHlwZSI6Im1hdHJpeCJ9fQAABAAAAG1ldGEAAAAAAgAAALQBAAAYAAAAAAASABgAFAATABIADAAAAAgABAASAAAAFAAAAGgBAABoAQAAAAADAWgBAAADAAAAvAAAACwAAAAEAAAAcP7//wgAAAAQAAAABQAAAFZhbHVlAAAABAAAAG5hbWUAAAAAlP7//wgAAAB4AAAAbQAAAHsiX19uYW1lX18iOiJwcm9tZXRoZXVzX2h0dHBfcmVxdWVzdHNfdG90YWwiLCJjb2RlIjoiNDAwIiwiaGFuZGxlciI6Ii9hcGkvdjEvcXVlcnlfcmFuZ2UiLCJqb2IiOiJwcm9tZXRoZXVzIn0AAAAGAAAAbGFiZWxzAAAg////CAAAAIQAAAB5AAAAeyJkaXNwbGF5TmFtZUZyb21EUyI6InByb21ldGhldXNfaHR0cF9yZXF1ZXN0c190b3RhbHtjb2RlPVwiNDAwXCIsIGhhbmRsZXI9XCIvYXBpL3YxL3F1ZXJ5X3JhbmdlXCIsIGpvYj1cInByb21ldGhldXNcIn0ifQAAAAYAAABjb25maWcAAAAAAACK////AAACAAUAAABWYWx1ZQASABgAFAAAABMADAAAAAgABAASAAAAFAAAAEQAAABMAAAAAAAACkwAAAABAAAADAAAAAgADAAIAAQACAAAAAgAAAAQAAAABAAAAFRpbWUAAAAABAAAAG5hbWUAAAAAAAAAAAAABgAIAAYABgAAAAAAAwAEAAAAVGltZQAAAAD/////uAAAABQAAAAAAAAADAAWABQAEwAMAAQADAAAADAAAAAAAAAAFAAAAAAAAAMDAAoAGAAMAAgABAAKAAAAFAAAAFgAAAADAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAYAAAAAAAAAAAAAAACAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAARBUU1CnJFgAOsE/UKckWANhKi9QpyRYAAAAAAABLQAAAAAAAQFBAAAAAAAAAU0AQAAAADAAUABIADAAIAAQADAAAABAAAAAsAAAAPAAAAAAAAwABAAAAUAMAAAAAAADAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAwAAAAIAAQACgAAAAgAAADsAAAAAwAAAKQAAAAoAAAABAAAAFD9//8IAAAADAAAAAAAAAAAAAAABQAAAHJlZklkAAAAcP3//wgAAABkAAAAWwAAAHByb21ldGhldXNfaHR0cF9yZXF1ZXN0c190b3RhbHtjb2RlPSI0MDAiLCBoYW5kbGVyPSIvYXBpL3YxL3F1ZXJ5X3JhbmdlIiwgam9iPSJwcm9tZXRoZXVzIn0ABAAAAG5hbWUAAAAA6P3//wgAAAAsAAAAIgAAAHsiY3VzdG9tIjp7InJlc3VsdFR5cGUiOiJtYXRyaXgifX0AAAQAAABtZXRhAAAAAAIAAAC0AQAAGAAAAAAAEgAYABQAEwASAAwAAAAIAAQAEgAAABQAAABoAQAAaAEAAAAAAwFoAQAAAwAAALwAAAAsAAAABAAAAHD+//8IAAAAEAAAAAUAAABWYWx1ZQAAAAQAAABuYW1lAAAAAJT+//8IAAAAeAAAAG0AAAB7Il9fbmFtZV9fIjoicHJvbWV0aGV1c19odHRwX3JlcXVlc3RzX3RvdGFsIiwiY29kZSI6IjQwMCIsImhhbmRsZXIiOiIvYXBpL3YxL3F1ZXJ5X3JhbmdlIiwiam9iIjoicHJvbWV0aGV1cyJ9AAAABgAAAGxhYmVscwAAIP///wgAAACEAAAAeQAAAHsiZGlzcGxheU5hbWVGcm9tRFMiOiJwcm9tZXRoZXVzX2h0dHBfcmVxdWVzdHNfdG90YWx7Y29kZT1cIjQwMFwiLCBoYW5kbGVyPVwiL2FwaS92MS9xdWVyeV9yYW5nZVwiLCBqb2I9XCJwcm9tZXRoZXVzXCJ9In0AAAAGAAAAY29uZmlnAAAAAAAAiv///wAAAgAFAAAAVmFsdWUAEgAYABQAAAATAAwAAAAIAAQAEgAAABQAAABEAAAATAAAAAAAAApMAAAAAQAAAAwAAAAIAAwACAAEAAgAAAAIAAAAEAAAAAQAAABUaW1lAAAAAAQAAABuYW1lAAAAAAAAAAAAAAYACAAGAAYAAAAAAAMABAAAAFRpbWUAAAAAcAMAAEFSUk9XMQ== diff --git a/pkg/tsdb/prometheus/testdata/range_simple.result.json b/pkg/tsdb/prometheus/testdata/range_simple.result.json new file mode 100644 index 00000000000..3c510aca9a3 --- /dev/null +++ b/pkg/tsdb/prometheus/testdata/range_simple.result.json @@ -0,0 +1,34 @@ +{ + "status": "success", + "data": { + "resultType": "matrix", + "result": [ + { + "metric": { + "__name__": "prometheus_http_requests_total", + "code": "200", + "handler": "/api/v1/query_range", + "job": "prometheus" + }, + "values": [ + [1641889530, "21"], + [1641889531, "32"], + [1641889532, "43"] + ] + }, + { + "metric": { + "__name__": "prometheus_http_requests_total", + "code": "400", + "handler": "/api/v1/query_range", + "job": "prometheus" + }, + "values": [ + [1641889530, "54"], + [1641889531, "65"], + [1641889532, "76"] + ] + } + ] + } +} diff --git a/pkg/tsdb/prometheus/time_series_query.go b/pkg/tsdb/prometheus/time_series_query.go index 83a8adac489..8abbf33a13d 100644 --- a/pkg/tsdb/prometheus/time_series_query.go +++ b/pkg/tsdb/prometheus/time_series_query.go @@ -47,21 +47,11 @@ const ( ExemplarQueryType TimeSeriesQueryType = "exemplar" ) -func (s *Service) executeTimeSeriesQuery(ctx context.Context, req *backend.QueryDataRequest, dsInfo *DatasourceInfo) (*backend.QueryDataResponse, error) { - client, err := dsInfo.getClient(req.Headers) - if err != nil { - return nil, err - } - +func runQueries(ctx context.Context, client apiv1.API, queries []*PrometheusQuery) (*backend.QueryDataResponse, error) { result := backend.QueryDataResponse{ Responses: backend.Responses{}, } - queries, err := s.parseTimeSeriesQuery(req, dsInfo) - if err != nil { - return &result, err - } - for _, query := range queries { plog.Debug("Sending query", "start", query.Start, "end", query.End, "step", query.Step, "query", query.Expr) @@ -124,6 +114,23 @@ func (s *Service) executeTimeSeriesQuery(ctx context.Context, req *backend.Query return &result, nil } +func (s *Service) executeTimeSeriesQuery(ctx context.Context, req *backend.QueryDataRequest, dsInfo *DatasourceInfo) (*backend.QueryDataResponse, error) { + client, err := dsInfo.getClient(req.Headers) + if err != nil { + return nil, err + } + + queries, err := s.parseTimeSeriesQuery(req, dsInfo) + if err != nil { + result := backend.QueryDataResponse{ + Responses: backend.Responses{}, + } + return &result, err + } + + return runQueries(ctx, client, queries) +} + func formatLegend(metric model.Metric, query *PrometheusQuery) string { var legend string