mirror of
https://github.com/grafana/grafana.git
synced 2024-11-28 19:54:10 -06:00
4c9469fc9e
* add `id` field to elasticsearch * add comment * slightly better perf * only add `id` to logs frames * only add `id` for logs responses * concat `index` and `id` * change snapshot generation to false * use better loop * fix tests * moved up
181 lines
5.9 KiB
Go
181 lines
5.9 KiB
Go
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
|
|
|
|
// If you need to adjust the snapshots, go to Line 172 and change
|
|
// `experimental.CheckGoldenJSONResponse(t, "testdata_response", goldenFileName, &dataResCopy, false)` to `experimental.CheckGoldenJSONResponse(t, "testdata_response", goldenFileName, &dataResCopy, true)`
|
|
// then run the test once to generate the new snapshots.
|
|
|
|
// 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"},
|
|
{name: "raw data test", path: "raw_data"},
|
|
{name: "raw document test", path: "raw_document"},
|
|
{name: "logs test", path: "logs"},
|
|
}
|
|
|
|
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"},
|
|
{name: "metric avg test", path: "metric_avg"},
|
|
{name: "metric percentiles test", path: "metric_percentiles"},
|
|
{name: "metric top_metrics test", path: "metric_top_metrics"},
|
|
{name: "metric extended_stats test", path: "metric_extended_stats"},
|
|
{name: "raw data test", path: "raw_data"},
|
|
{name: "logs test", path: "logs"},
|
|
}
|
|
|
|
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, strings.ToLower(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)
|
|
}
|
|
})
|
|
}
|
|
}
|