forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathquerydata_test.go
161 lines (132 loc) · 4.18 KB
/
querydata_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package elasticsearch
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
es "github.com/grafana/grafana/pkg/tsdb/elasticsearch/client"
)
type queryDataTestRoundTripper struct {
requestCallback func(req *http.Request) error
body []byte
statusCode int
}
// 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: rt.statusCode,
Header: http.Header{},
Body: io.NopCloser(bytes.NewReader(rt.body)),
}, nil
}
// we setup a fake datasource-info
func newFlowTestDsInfo(body []byte, statusCode int, requestCallback func(req *http.Request) error) *es.DatasourceInfo {
client := http.Client{
Transport: &queryDataTestRoundTripper{body: body, statusCode: statusCode, requestCallback: requestCallback},
}
configuredFields := es.ConfiguredFields{
TimeField: "testtime",
LogMessageField: "line",
LogLevelField: "lvl",
}
return &es.DatasourceInfo{
Interval: "Daily",
Database: "[testdb-]YYYY.MM.DD",
ConfiguredFields: configuredFields,
URL: "http://localhost:9200",
HTTPClient: &client,
MaxConcurrentShardRequests: 42,
IncludeFrozen: false,
}
}
type queryDataTestQueryJSON struct {
IntervalMs int64
Interval time.Duration
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)
}
queries := make([]backend.DataQuery, len(jsonBytesArray))
for i, 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: jsonInfo.Interval,
TimeRange: timeRange,
JSON: jsonBytes,
}
queries[i] = query
}
return queries, nil
}
type queryDataTestResult struct {
response *backend.QueryDataResponse
requestBytes []byte
}
func queryDataTestWithResponseCode(queriesBytes []byte, responseStatusCode int, responseBytes []byte) (queryDataTestResult, error) {
queries, err := newFlowTestQueries(queriesBytes)
req := backend.QueryDataRequest{
Queries: queries,
}
if err != nil {
return queryDataTestResult{}, err
}
requestBytesStored := false
var requestBytes []byte
dsInfo := newFlowTestDsInfo(responseBytes, responseStatusCode, 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(), &req, dsInfo, log.New())
if err != nil {
return queryDataTestResult{}, err
}
if !requestBytesStored {
return queryDataTestResult{}, fmt.Errorf("request-bytes not stored")
}
return queryDataTestResult{
response: result,
requestBytes: requestBytes,
}, nil
}
func queryDataTest(queriesBytes []byte, responseBytes []byte) (queryDataTestResult, error) {
return queryDataTestWithResponseCode(queriesBytes, 200, responseBytes)
}