elastic: add more backend tests (#59312)

* elastic: added backend snapshot tests

* linter fixes
This commit is contained in:
Gábor Farkas 2022-11-28 14:59:57 +01:00 committed by GitHub
parent a7b2943dd1
commit f1dfaa784a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1818 additions and 3 deletions

View File

@ -42,22 +42,27 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest)
return &backend.QueryDataResponse{}, err
}
return queryData(ctx, req.Queries, dsInfo, s.intervalCalculator)
}
// separate function to allow testing the whole transformation and query flow
func queryData(ctx context.Context, queries []backend.DataQuery, dsInfo *es.DatasourceInfo, intervalCalculator intervalv2.Calculator) (*backend.QueryDataResponse, error) {
// Support for version after their end-of-life (currently <7.10.0) was removed
lastSupportedVersion, _ := semver.NewVersion("7.10.0")
if dsInfo.ESVersion.LessThan(lastSupportedVersion) {
return &backend.QueryDataResponse{}, fmt.Errorf("support for elasticsearch versions after their end-of-life (currently versions < 7.10) was removed")
}
if len(req.Queries) == 0 {
if len(queries) == 0 {
return &backend.QueryDataResponse{}, fmt.Errorf("query contains no queries")
}
client, err := es.NewClient(ctx, dsInfo, req.Queries[0].TimeRange)
client, err := es.NewClient(ctx, dsInfo, queries[0].TimeRange)
if err != nil {
return &backend.QueryDataResponse{}, err
}
query := newTimeSeriesQuery(client, req.Queries, s.intervalCalculator)
query := newTimeSeriesQuery(client, queries, intervalCalculator)
return query.execute()
}

View File

@ -0,0 +1,146 @@
package elasticsearch
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"github.com/Masterminds/semver"
"github.com/grafana/grafana-plugin-sdk-go/backend"
es "github.com/grafana/grafana/pkg/tsdb/elasticsearch/client"
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
)
type queryDataTestRoundTripper struct {
requestCallback func(req *http.Request) error
body []byte
}
// we fake the http-request-call. we return a fixed byte-array (defined by the test snapshot),
// and we also check if the http-request-object has the correct data
func (rt *queryDataTestRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
err := rt.requestCallback(req)
if err != nil {
return nil, err
}
return &http.Response{
StatusCode: http.StatusOK,
Header: http.Header{},
Body: io.NopCloser(bytes.NewReader(rt.body)),
}, nil
}
// we setup a fake datasource-info
func newFlowTestDsInfo(body []byte, reuestCallback func(req *http.Request) error) *es.DatasourceInfo {
client := http.Client{
Transport: &queryDataTestRoundTripper{body: body, requestCallback: reuestCallback},
}
return &es.DatasourceInfo{
ESVersion: semver.MustParse("8.5.0"),
Interval: "Daily",
Database: "[testdb-]YYYY.MM.DD",
TimeField: "testtime",
TimeInterval: "1s",
URL: "http://localhost:9200",
HTTPClient: &client,
MaxConcurrentShardRequests: 42,
IncludeFrozen: false,
XPack: true,
}
}
type queryDataTestQueryJSON struct {
IntervalMs int64
MaxDataPoints int64
RefID string
}
// we take an array of json-bytes, that define the elastic queries,
// and create full backend.DataQuery objects from them
func newFlowTestQueries(allJsonBytes []byte) ([]backend.DataQuery, error) {
timeRange := backend.TimeRange{
From: time.UnixMilli(1668422437218),
To: time.UnixMilli(1668422625668),
}
// we will need every separate query-item as a json-byte-array later,
// so we only decode the "array", and keep the "items" undecoded.
var jsonBytesArray []json.RawMessage
err := json.Unmarshal(allJsonBytes, &jsonBytesArray)
if err != nil {
return nil, fmt.Errorf("error unmarshaling query-json: %w", err)
}
var queries []backend.DataQuery
for _, jsonBytes := range jsonBytesArray {
// we need to extract some fields from the json-array
var jsonInfo queryDataTestQueryJSON
err = json.Unmarshal(jsonBytes, &jsonInfo)
if err != nil {
return nil, err
}
// we setup the DataQuery, with values loaded from the json
query := backend.DataQuery{
RefID: jsonInfo.RefID,
MaxDataPoints: jsonInfo.MaxDataPoints,
Interval: time.Duration(jsonInfo.IntervalMs) * time.Millisecond,
TimeRange: timeRange,
JSON: jsonBytes,
}
queries = append(queries, query)
}
return queries, nil
}
type queryDataTestResult struct {
response *backend.QueryDataResponse
requestBytes []byte
}
func queryDataTest(queriesBytes []byte, responseBytes []byte) (queryDataTestResult, error) {
queries, err := newFlowTestQueries(queriesBytes)
if err != nil {
return queryDataTestResult{}, err
}
requestBytesStored := false
var requestBytes []byte
dsInfo := newFlowTestDsInfo(responseBytes, func(req *http.Request) error {
requestBytes, err = io.ReadAll(req.Body)
bodyCloseError := req.Body.Close()
if err != nil {
return err
}
if bodyCloseError != nil {
return bodyCloseError
}
requestBytesStored = true
return nil
})
result, err := queryData(context.Background(), queries, dsInfo, intervalv2.NewCalculator())
if err != nil {
return queryDataTestResult{}, err
}
if !requestBytesStored {
return queryDataTestResult{}, fmt.Errorf("request-bytes not stored")
}
return queryDataTestResult{
response: result,
requestBytes: requestBytes,
}, nil
}

View File

@ -0,0 +1,167 @@
package elasticsearch
import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
"github.com/grafana/grafana-plugin-sdk-go/experimental"
"github.com/stretchr/testify/require"
)
// these snapshot-tests test the whole request-response flow:
// the inputs:
// - the backend.DataQuery query
// - the elastic-response json
// the snapshot verifies:
// - the elastic-request json
// - the dataframe result
// a regex that matches the request-snapshot-filenames, and extracts the name of the test
var requestRe = regexp.MustCompile(`^(.*)\.request\.line\d+\.json$`)
// the "elastic request" is often in multiple json-snapshot-files,
// so we have to find them on disk, so we have to look at every file in
// the folder.
func findRequestSnapshots(t *testing.T, folder string) map[string][]string {
allTestSnapshotFiles, err := os.ReadDir(folder)
require.NoError(t, err)
snapshots := make(map[string][]string)
for _, file := range allTestSnapshotFiles {
fileName := file.Name()
match := requestRe.FindStringSubmatch(fileName)
if len(match) == 2 {
testName := match[1]
files := append(snapshots[testName], filepath.Join(folder, fileName))
snapshots[testName] = files
}
}
return snapshots
}
// a regex that matches the response-snapshot-filenames, and extracts the name of the test
var responseRe = regexp.MustCompile(`^([^\.]+)\.[^\.]+.golden.jsonc$`)
func findResponseSnapshotCounts(t *testing.T, folder string) map[string]int {
allTestSnapshotFiles, err := os.ReadDir(folder)
require.NoError(t, err)
snapshots := make(map[string]int)
for _, file := range allTestSnapshotFiles {
fileName := file.Name()
match := responseRe.FindStringSubmatch(fileName)
if len(match) == 2 {
testName := match[1]
snapshots[testName] = snapshots[testName] + 1
}
}
return snapshots
}
func TestRequestSnapshots(t *testing.T) {
tt := []struct {
name string
path string
}{
{name: "simple metric test", path: "metric_simple"},
{name: "complex metric test", path: "metric_complex"},
{name: "multi metric test", path: "metric_multi"},
}
queryHeader := []byte(`
{
"ignore_unavailable": true,
"index": "testdb-2022.11.14",
"search_type": "query_then_fetch"
}
`)
requestSnapshots := findRequestSnapshots(t, "testdata_request")
for _, test := range tt {
t.Run(test.name, func(t *testing.T) {
responseBytes := []byte(`{"responses":[]}`)
queriesFileName := filepath.Join("testdata_request", test.path+".queries.json")
queriesBytes, err := os.ReadFile(filepath.Clean(queriesFileName))
require.NoError(t, err)
var requestLines [][]byte
for _, fileName := range requestSnapshots[test.path] {
bytes, err := os.ReadFile(filepath.Clean(fileName))
require.NoError(t, err)
requestLines = append(requestLines, bytes)
}
require.True(t, len(requestLines) > 0, "requestLines must not be empty")
result, err := queryDataTest(queriesBytes, responseBytes)
require.NoError(t, err)
reqLines := strings.Split(strings.TrimSpace(string(result.requestBytes)), "\n")
require.Len(t, reqLines, len(requestLines)*2)
for i, expectedRequestLine := range requestLines {
actualRequestHeaderLine := reqLines[2*i]
actualRequestLine := reqLines[2*i+1]
require.JSONEq(t, string(queryHeader), actualRequestHeaderLine, fmt.Sprintf("invalid request-header at index: %v", i))
require.JSONEq(t, string(expectedRequestLine), actualRequestLine, fmt.Sprintf("invalid request at index: %v", i))
}
})
}
}
func TestResponseSnapshots(t *testing.T) {
tt := []struct {
name string
path string
}{
{name: "simple metric test", path: "metric_simple"},
{name: "complex metric test", path: "metric_complex"},
{name: "multi metric test", path: "metric_multi"},
}
snapshotCount := findResponseSnapshotCounts(t, "testdata_response")
for _, test := range tt {
t.Run(test.name, func(t *testing.T) {
responseFileName := filepath.Join("testdata_response", test.path+".response.json")
responseBytes, err := os.ReadFile(filepath.Clean(responseFileName))
require.NoError(t, err)
queriesFileName := filepath.Join("testdata_response", test.path+".queries.json")
queriesBytes, err := os.ReadFile(filepath.Clean(queriesFileName))
require.NoError(t, err)
result, err := queryDataTest(queriesBytes, responseBytes)
require.NoError(t, err)
// first we need to test that the number of items in `result.response.Responses`,
// is exactly the same as the count of our response snapshot files
// (this is so that we avoid situations where we provide more snapshot-files than
// what is returned)
expectedResponseCount := snapshotCount[test.path]
require.True(t, expectedResponseCount > 0, "response snapshots not found")
require.Len(t, result.response.Responses, expectedResponseCount)
for refId, dataRes := range result.response.Responses {
goldenFileName := fmt.Sprintf("%v.%v.golden", test.path, refId)
// we make a copy of the variable to avoid this linter-warning:
// "G601: Implicit memory aliasing in for loop."
dataResCopy := dataRes
experimental.CheckGoldenJSONResponse(t, "testdata_response", goldenFileName, &dataResCopy, false)
}
})
}
}

View File

@ -0,0 +1,52 @@
[
{
"alias": "",
"bucketAggs": [
{
"field": "label",
"id": "4",
"settings": {
"min_doc_count": "1",
"order": "desc",
"orderBy": "_term",
"size": "10"
},
"type": "terms"
},
{
"field": "testtime",
"id": "2",
"settings": {
"interval": "1m",
"min_doc_count": "0",
"timeZone": "utc",
"trimEdges": "0"
},
"type": "date_histogram"
}
],
"datasource": {
"uid": "haha",
"type": "elasticsearch"
},
"datasourceId": 42,
"hide": true,
"metrics": [
{
"field": "float",
"id": "1",
"type": "max"
},
{
"field": "float",
"id": "3",
"type": "min"
}
],
"query": "",
"refId": "a",
"timeField": "testtime",
"intervalMs": 200,
"maxDataPoints": 779
}
]

View File

@ -0,0 +1,53 @@
{
"aggs": {
"4": {
"aggs": {
"2": {
"aggs": {
"1": {
"max": {
"field": "float"
}
},
"3": {
"min": {
"field": "float"
}
}
},
"date_histogram": {
"extended_bounds": {
"max": 1668422625668,
"min": 1668422437218
},
"field": "testtime",
"fixed_interval": "1m",
"format": "epoch_millis",
"min_doc_count": 0
}
}
},
"terms": {
"field": "label",
"order": {
"_key": "desc"
},
"size": 10
}
}
},
"query": {
"bool": {
"filter": {
"range": {
"testtime": {
"format": "epoch_millis",
"gte": 1668422437218,
"lte": 1668422625668
}
}
}
}
},
"size": 0
}

View File

@ -0,0 +1,41 @@
[
{
"refId": "a",
"datasource": { "uid": "haha", "type": "elasticsearch" },
"datasourceId": 42,
"query": "",
"alias": "",
"metrics": [{ "id": "1", "type": "max", "field": "float" }],
"bucketAggs": [
{
"type": "date_histogram",
"id": "2",
"settings": { "interval": "auto" },
"field": "testtime"
}
],
"timeField": "testtime",
"intervalMs": 30000,
"maxDataPoints": 814
},
{
"datasource": { "uid": "haha", "type": "elasticsearch" },
"datasourceId": 42,
"refId": "b",
"hide": false,
"query": "",
"alias": "",
"metrics": [{ "id": "1", "type": "min", "field": "float" }],
"bucketAggs": [
{
"type": "date_histogram",
"id": "2",
"settings": { "interval": "auto" },
"field": "testtime"
}
],
"timeField": "testtime",
"intervalMs": 30000,
"maxDataPoints": 814
}
]

View File

@ -0,0 +1,37 @@
{
"size": 0,
"query": {
"bool": {
"filter": {
"range": {
"testtime": {
"gte": 1668422437218,
"lte": 1668422625668,
"format": "epoch_millis"
}
}
}
}
},
"aggs": {
"2": {
"date_histogram": {
"field": "testtime",
"min_doc_count": 0,
"extended_bounds": {
"min": 1668422437218,
"max": 1668422625668
},
"format": "epoch_millis",
"fixed_interval": "1000ms"
},
"aggs": {
"1": {
"max": {
"field": "float"
}
}
}
}
}
}

View File

@ -0,0 +1,37 @@
{
"size": 0,
"query": {
"bool": {
"filter": {
"range": {
"testtime": {
"gte": 1668422437218,
"lte": 1668422625668,
"format": "epoch_millis"
}
}
}
}
},
"aggs": {
"2": {
"date_histogram": {
"field": "testtime",
"min_doc_count": 0,
"extended_bounds": {
"min": 1668422437218,
"max": 1668422625668
},
"format": "epoch_millis",
"fixed_interval": "1000ms"
},
"aggs": {
"1": {
"min": {
"field": "float"
}
}
}
}
}
}

View File

@ -0,0 +1,45 @@
[
{
"alias": "",
"bucketAggs": [
{
"field": "label",
"id": "3",
"settings": {
"min_doc_count": "1",
"order": "desc",
"orderBy": "_term",
"size": "10"
},
"type": "terms"
},
{
"field": "testtime",
"id": "2",
"settings": {
"interval": "1m"
},
"type": "date_histogram"
}
],
"datasource": {
"type": "elasticsearch",
"uid": "haha"
},
"datasourceId": 42,
"expression": "",
"hide": true,
"intervalMs": 200,
"maxDataPoints": 1248,
"metrics": [
{
"id": "1",
"type": "count"
}
],
"query": "",
"refId": "a",
"timeField": "testtime",
"window": ""
}
]

View File

@ -0,0 +1,43 @@
{
"aggs": {
"3": {
"aggs": {
"2": {
"date_histogram": {
"extended_bounds": {
"max": 1668422625668,
"min": 1668422437218
},
"field": "testtime",
"fixed_interval": "1m",
"format": "epoch_millis",
"min_doc_count": 0
}
}
},
"terms": {
"field": "label",
"order": {
"_key": "desc"
},
"size": 10
}
}
},
"query": {
"bool": {
"filter": {
"range": {
"testtime": {
"format": "epoch_millis",
"gte": 1668422437218,
"lte": 1668422625668
}
}
}
}
},
"size": 0
}

View File

@ -0,0 +1,391 @@
// 🌟 This was machine generated. Do not edit. 🌟
//
// Frame[0] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 3 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val3 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-22 12:45:00 +0000 UTC | 97.85990905761719 |
// | 2022-11-22 12:46:00 +0000 UTC | 98.39459228515625 |
// | 2022-11-22 12:47:00 +0000 UTC | 99.76652526855469 |
// +-------------------------------+--------------------+
//
//
//
// Frame[1] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 3 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val3 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-22 12:45:00 +0000 UTC | 8.375883102416992 |
// | 2022-11-22 12:46:00 +0000 UTC | 0.2577083110809326 |
// | 2022-11-22 12:47:00 +0000 UTC | 6.422464847564697 |
// +-------------------------------+--------------------+
//
//
//
// Frame[2] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 3 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val2 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-22 12:45:00 +0000 UTC | 87.77692413330078 |
// | 2022-11-22 12:46:00 +0000 UTC | 98.47160339355469 |
// | 2022-11-22 12:47:00 +0000 UTC | 92.53878784179688 |
// +-------------------------------+--------------------+
//
//
//
// Frame[3] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 3 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val2 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-22 12:45:00 +0000 UTC | 4.540984630584717 |
// | 2022-11-22 12:46:00 +0000 UTC | 3.343874216079712 |
// | 2022-11-22 12:47:00 +0000 UTC | 26.237546920776367 |
// +-------------------------------+--------------------+
//
//
//
// Frame[4] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 3 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val1 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-22 12:45:00 +0000 UTC | 98.57181549072266 |
// | 2022-11-22 12:46:00 +0000 UTC | 97.99356079101562 |
// | 2022-11-22 12:47:00 +0000 UTC | 94.45416259765625 |
// +-------------------------------+--------------------+
//
//
//
// Frame[5] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 3 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val1 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-22 12:45:00 +0000 UTC | 2.859630584716797 |
// | 2022-11-22 12:46:00 +0000 UTC | 0.4383751451969147 |
// | 2022-11-22 12:47:00 +0000 UTC | 1.4335381984710693 |
// +-------------------------------+--------------------+
//
//
// 🌟 This was machine generated. Do not edit. 🌟
{
"status": 200,
"frames": [
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val3 Max float"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val3"
},
"config": {
"displayNameFromDS": "val3 Max float"
}
}
]
},
"data": {
"values": [
[
1669121100000,
1669121160000,
1669121220000
],
[
97.85990905761719,
98.39459228515625,
99.76652526855469
]
]
}
},
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val3 Min float"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val3"
},
"config": {
"displayNameFromDS": "val3 Min float"
}
}
]
},
"data": {
"values": [
[
1669121100000,
1669121160000,
1669121220000
],
[
8.375883102416992,
0.2577083110809326,
6.422464847564697
]
]
}
},
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val2 Max float"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val2"
},
"config": {
"displayNameFromDS": "val2 Max float"
}
}
]
},
"data": {
"values": [
[
1669121100000,
1669121160000,
1669121220000
],
[
87.77692413330078,
98.47160339355469,
92.53878784179688
]
]
}
},
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val2 Min float"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val2"
},
"config": {
"displayNameFromDS": "val2 Min float"
}
}
]
},
"data": {
"values": [
[
1669121100000,
1669121160000,
1669121220000
],
[
4.540984630584717,
3.343874216079712,
26.237546920776367
]
]
}
},
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val1 Max float"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val1"
},
"config": {
"displayNameFromDS": "val1 Max float"
}
}
]
},
"data": {
"values": [
[
1669121100000,
1669121160000,
1669121220000
],
[
98.57181549072266,
97.99356079101562,
94.45416259765625
]
]
}
},
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val1 Min float"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val1"
},
"config": {
"displayNameFromDS": "val1 Min float"
}
}
]
},
"data": {
"values": [
[
1669121100000,
1669121160000,
1669121220000
],
[
2.859630584716797,
0.4383751451969147,
1.4335381984710693
]
]
}
}
]
}

View File

@ -0,0 +1,52 @@
[
{
"alias": "",
"bucketAggs": [
{
"field": "label",
"id": "4",
"settings": {
"min_doc_count": "1",
"order": "desc",
"orderBy": "_term",
"size": "10"
},
"type": "terms"
},
{
"field": "testtime",
"id": "2",
"settings": {
"interval": "1m",
"min_doc_count": "0",
"timeZone": "utc",
"trimEdges": "0"
},
"type": "date_histogram"
}
],
"datasource": {
"uid": "haha",
"type": "elasticsearch"
},
"datasourceId": 42,
"hide": true,
"metrics": [
{
"field": "float",
"id": "1",
"type": "max"
},
{
"field": "float",
"id": "3",
"type": "min"
}
],
"query": "",
"refId": "a",
"timeField": "testtime",
"intervalMs": 200,
"maxDataPoints": 779
}
]

View File

@ -0,0 +1,155 @@
{
"took": 4,
"responses": [
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 187,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"4": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "val3",
"doc_count": 60,
"2": {
"buckets": [
{
"key_as_string": "1669121100000",
"key": 1669121100000,
"doc_count": 14,
"1": {
"value": 97.85990905761719
},
"3": {
"value": 8.375883102416992
}
},
{
"key_as_string": "1669121160000",
"key": 1669121160000,
"doc_count": 42,
"1": {
"value": 98.39459228515625
},
"3": {
"value": 0.2577083110809326
}
},
{
"key_as_string": "1669121220000",
"key": 1669121220000,
"doc_count": 4,
"1": {
"value": 99.76652526855469
},
"3": {
"value": 6.422464847564697
}
}
]
}
},
{
"key": "val2",
"doc_count": 68,
"2": {
"buckets": [
{
"key_as_string": "1669121100000",
"key": 1669121100000,
"doc_count": 14,
"1": {
"value": 87.77692413330078
},
"3": {
"value": 4.540984630584717
}
},
{
"key_as_string": "1669121160000",
"key": 1669121160000,
"doc_count": 45,
"1": {
"value": 98.47160339355469
},
"3": {
"value": 3.343874216079712
}
},
{
"key_as_string": "1669121220000",
"key": 1669121220000,
"doc_count": 9,
"1": {
"value": 92.53878784179688
},
"3": {
"value": 26.237546920776367
}
}
]
}
},
{
"key": "val1",
"doc_count": 59,
"2": {
"buckets": [
{
"key_as_string": "1669121100000",
"key": 1669121100000,
"doc_count": 18,
"1": {
"value": 98.57181549072266
},
"3": {
"value": 2.859630584716797
}
},
{
"key_as_string": "1669121160000",
"key": 1669121160000,
"doc_count": 32,
"1": {
"value": 97.99356079101562
},
"3": {
"value": 0.4383751451969147
}
},
{
"key_as_string": "1669121220000",
"key": 1669121220000,
"doc_count": 9,
"1": {
"value": 94.45416259765625
},
"3": {
"value": 1.4335381984710693
}
}
]
}
}
]
}
},
"status": 200
}
]
}

View File

@ -0,0 +1,69 @@
// 🌟 This was machine generated. Do not edit. 🌟
//
// Frame[0] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 3 Rows
// +-------------------------------+-------------------+
// | Name: time | Name: value |
// | Labels: | Labels: |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+-------------------+
// | 2022-11-28 10:59:00 +0000 UTC | 97.96025848388672 |
// | 2022-11-28 11:00:00 +0000 UTC | 98.74357604980469 |
// | 2022-11-28 11:01:00 +0000 UTC | 99.94505310058594 |
// +-------------------------------+-------------------+
//
//
// 🌟 This was machine generated. Do not edit. 🌟
{
"status": 200,
"frames": [
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "Max float"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {},
"config": {
"displayNameFromDS": "Max float"
}
}
]
},
"data": {
"values": [
[
1669633140000,
1669633200000,
1669633260000
],
[
97.96025848388672,
98.74357604980469,
99.94505310058594
]
]
}
}
]
}

View File

@ -0,0 +1,69 @@
// 🌟 This was machine generated. Do not edit. 🌟
//
// Frame[0] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 3 Rows
// +-------------------------------+---------------------+
// | Name: time | Name: value |
// | Labels: | Labels: |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+---------------------+
// | 2022-11-28 10:59:00 +0000 UTC | 1.8121581077575684 |
// | 2022-11-28 11:00:00 +0000 UTC | 0.776007354259491 |
// | 2022-11-28 11:01:00 +0000 UTC | 0.26452451944351196 |
// +-------------------------------+---------------------+
//
//
// 🌟 This was machine generated. Do not edit. 🌟
{
"status": 200,
"frames": [
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "Min float"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {},
"config": {
"displayNameFromDS": "Min float"
}
}
]
},
"data": {
"values": [
[
1669633140000,
1669633200000,
1669633260000
],
[
1.8121581077575684,
0.776007354259491,
0.26452451944351196
]
]
}
}
]
}

View File

@ -0,0 +1,41 @@
[
{
"refId": "a",
"datasource": { "uid": "haha", "type": "elasticsearch" },
"datasourceId": 42,
"query": "",
"alias": "",
"metrics": [{ "id": "1", "type": "max", "field": "float" }],
"bucketAggs": [
{
"type": "date_histogram",
"id": "2",
"settings": { "interval": "auto" },
"field": "testtime"
}
],
"timeField": "testtime",
"intervalMs": 30000,
"maxDataPoints": 814
},
{
"datasource": { "uid": "haha", "type": "elasticsearch" },
"datasourceId": 42,
"refId": "b",
"hide": false,
"query": "",
"alias": "",
"metrics": [{ "id": "1", "type": "min", "field": "float" }],
"bucketAggs": [
{
"type": "date_histogram",
"id": "2",
"settings": { "interval": "auto" },
"field": "testtime"
}
],
"timeField": "testtime",
"intervalMs": 30000,
"maxDataPoints": 814
}
]

View File

@ -0,0 +1,103 @@
{
"took": 5,
"responses": [
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 188,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"2": {
"buckets": [
{
"key_as_string": "1669633140000",
"key": 1669633140000,
"doc_count": 34,
"1": {
"value": 97.96025848388672
}
},
{
"key_as_string": "1669633200000",
"key": 1669633200000,
"doc_count": 74,
"1": {
"value": 98.74357604980469
}
},
{
"key_as_string": "1669633260000",
"key": 1669633260000,
"doc_count": 80,
"1": {
"value": 99.94505310058594
}
}
]
}
},
"status": 200
},
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 188,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"2": {
"buckets": [
{
"key_as_string": "1669633140000",
"key": 1669633140000,
"doc_count": 34,
"1": {
"value": 1.8121581077575684
}
},
{
"key_as_string": "1669633200000",
"key": 1669633200000,
"doc_count": 74,
"1": {
"value": 0.776007354259491
}
},
{
"key_as_string": "1669633260000",
"key": 1669633260000,
"doc_count": 80,
"1": {
"value": 0.26452451944351196
}
}
]
}
},
"status": 200
}
]
}

View File

@ -0,0 +1,208 @@
// 🌟 This was machine generated. Do not edit. 🌟
//
// Frame[0] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 4 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val3 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-14 10:40:00 +0000 UTC | 0 |
// | 2022-11-14 10:41:00 +0000 UTC | 27 |
// | 2022-11-14 10:42:00 +0000 UTC | 21 |
// | 2022-11-14 10:43:00 +0000 UTC | 31 |
// +-------------------------------+--------------------+
//
//
//
// Frame[1] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 4 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val2 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-14 10:40:00 +0000 UTC | 0 |
// | 2022-11-14 10:41:00 +0000 UTC | 28 |
// | 2022-11-14 10:42:00 +0000 UTC | 22 |
// | 2022-11-14 10:43:00 +0000 UTC | 39 |
// +-------------------------------+--------------------+
//
//
//
// Frame[2] {
// "custom": null
// }
// Name:
// Dimensions: 2 Fields by 4 Rows
// +-------------------------------+--------------------+
// | Name: time | Name: value |
// | Labels: | Labels: label=val1 |
// | Type: []time.Time | Type: []*float64 |
// +-------------------------------+--------------------+
// | 2022-11-14 10:40:00 +0000 UTC | 0 |
// | 2022-11-14 10:41:00 +0000 UTC | 26 |
// | 2022-11-14 10:42:00 +0000 UTC | 20 |
// | 2022-11-14 10:43:00 +0000 UTC | 41 |
// +-------------------------------+--------------------+
//
//
// 🌟 This was machine generated. Do not edit. 🌟
{
"status": 200,
"frames": [
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val3"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val3"
},
"config": {
"displayNameFromDS": "val3"
}
}
]
},
"data": {
"values": [
[
1668422400000,
1668422460000,
1668422520000,
1668422580000
],
[
0,
27,
21,
31
]
]
}
},
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val2"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val2"
},
"config": {
"displayNameFromDS": "val2"
}
}
]
},
"data": {
"values": [
[
1668422400000,
1668422460000,
1668422520000,
1668422580000
],
[
0,
28,
22,
39
]
]
}
},
{
"schema": {
"meta": {
"custom": null
},
"fields": [
{
"name": "time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"displayNameFromDS": "val1"
}
},
{
"name": "value",
"type": "number",
"typeInfo": {
"frame": "float64",
"nullable": true
},
"labels": {
"label": "val1"
},
"config": {
"displayNameFromDS": "val1"
}
}
]
},
"data": {
"values": [
[
1668422400000,
1668422460000,
1668422520000,
1668422580000
],
[
0,
26,
20,
41
]
]
}
}
]
}

View File

@ -0,0 +1,45 @@
[
{
"alias": "",
"bucketAggs": [
{
"field": "label",
"id": "3",
"settings": {
"min_doc_count": "1",
"order": "desc",
"orderBy": "_term",
"size": "10"
},
"type": "terms"
},
{
"field": "testtime",
"id": "2",
"settings": {
"interval": "1m"
},
"type": "date_histogram"
}
],
"datasource": {
"type": "elasticsearch",
"uid": "haha"
},
"datasourceId": 42,
"expression": "",
"hide": true,
"intervalMs": 200,
"maxDataPoints": 1248,
"metrics": [
{
"id": "1",
"type": "count"
}
],
"query": "",
"refId": "a",
"timeField": "testtime",
"window": ""
}
]

View File

@ -0,0 +1,56 @@
{
"took": 7,
"responses": [
{
"took": 7,
"timed_out": false,
"_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 },
"hits": { "total": { "value": 255, "relation": "eq" }, "max_score": null, "hits": [] },
"aggregations": {
"3": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "val3",
"doc_count": 79,
"2": {
"buckets": [
{ "key_as_string": "1668422400000", "key": 1668422400000, "doc_count": 0 },
{ "key_as_string": "1668422460000", "key": 1668422460000, "doc_count": 27 },
{ "key_as_string": "1668422520000", "key": 1668422520000, "doc_count": 21 },
{ "key_as_string": "1668422580000", "key": 1668422580000, "doc_count": 31 }
]
}
},
{
"key": "val2",
"doc_count": 89,
"2": {
"buckets": [
{ "key_as_string": "1668422400000", "key": 1668422400000, "doc_count": 0 },
{ "key_as_string": "1668422460000", "key": 1668422460000, "doc_count": 28 },
{ "key_as_string": "1668422520000", "key": 1668422520000, "doc_count": 22 },
{ "key_as_string": "1668422580000", "key": 1668422580000, "doc_count": 39 }
]
}
},
{
"key": "val1",
"doc_count": 87,
"2": {
"buckets": [
{ "key_as_string": "1668422400000", "key": 1668422400000, "doc_count": 0 },
{ "key_as_string": "1668422460000", "key": 1668422460000, "doc_count": 26 },
{ "key_as_string": "1668422520000", "key": 1668422520000, "doc_count": 20 },
{ "key_as_string": "1668422580000", "key": 1668422580000, "doc_count": 41 }
]
}
}
]
}
},
"status": 200
}
]
}