mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 18:44:54 +08:00
Chore: Code cleaning with unit tests in promlib (#99542)
* update request tests * remove unused functions * add unit tests * remove commented code * fix unit tests
This commit is contained in:
@ -2,7 +2,6 @@ package promlib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -11,7 +10,6 @@ import (
|
|||||||
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||||
apiv1 "github.com/prometheus/client_golang/api/prometheus/v1"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/promlib/client"
|
"github.com/grafana/grafana/pkg/promlib/client"
|
||||||
"github.com/grafana/grafana/pkg/promlib/instrumentation"
|
"github.com/grafana/grafana/pkg/promlib/instrumentation"
|
||||||
@ -138,18 +136,3 @@ func (s *Service) getInstance(ctx context.Context, pluginCtx backend.PluginConte
|
|||||||
in := i.(instance)
|
in := i.(instance)
|
||||||
return &in, nil
|
return &in, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAPIError returns whether err is or wraps a Prometheus error.
|
|
||||||
func IsAPIError(err error) bool {
|
|
||||||
// Check if the right error type is in err's chain.
|
|
||||||
var e *apiv1.Error
|
|
||||||
return errors.As(err, &e)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertAPIError(err error) error {
|
|
||||||
var e *apiv1.Error
|
|
||||||
if errors.As(err, &e) {
|
|
||||||
return fmt.Errorf("%s: %s", e.Msg, e.Detail)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
@ -43,7 +43,7 @@ func BenchmarkExemplarJson(b *testing.B) {
|
|||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: io.NopCloser(bytes.NewReader(responseBytes)),
|
Body: io.NopCloser(bytes.NewReader(responseBytes)),
|
||||||
}
|
}
|
||||||
tCtx.httpProvider.setResponse(&res)
|
tCtx.httpProvider.setResponse(&res, &res)
|
||||||
resp, err := tCtx.queryData.Execute(context.Background(), query)
|
resp, err := tCtx.queryData.Execute(context.Background(), query)
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
for _, r := range resp.Responses {
|
for _, r := range resp.Responses {
|
||||||
@ -74,7 +74,7 @@ func BenchmarkRangeJson(b *testing.B) {
|
|||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: io.NopCloser(bytes.NewReader(body)),
|
Body: io.NopCloser(bytes.NewReader(body)),
|
||||||
}
|
}
|
||||||
tCtx.httpProvider.setResponse(&res)
|
tCtx.httpProvider.setResponse(&res, &res)
|
||||||
r, err = tCtx.queryData.Execute(context.Background(), q)
|
r, err = tCtx.queryData.Execute(context.Background(), q)
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,6 @@ func runQuery(response []byte, q *backend.QueryDataRequest) (*backend.QueryDataR
|
|||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: io.NopCloser(bytes.NewReader(response)),
|
Body: io.NopCloser(bytes.NewReader(response)),
|
||||||
}
|
}
|
||||||
tCtx.httpProvider.setResponse(res)
|
tCtx.httpProvider.setResponse(res, res)
|
||||||
return tCtx.queryData.Execute(context.Background(), q)
|
return tCtx.queryData.Execute(context.Background(), q)
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import (
|
|||||||
|
|
||||||
func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
||||||
t.Run("exemplars response should be sampled and parsed normally", func(t *testing.T) {
|
t.Run("exemplars response should be sampled and parsed normally", func(t *testing.T) {
|
||||||
t.Skip()
|
|
||||||
exemplars := []apiv1.ExemplarQueryResult{
|
exemplars := []apiv1.ExemplarQueryResult{
|
||||||
{
|
{
|
||||||
SeriesLabels: p.LabelSet{
|
SeriesLabels: p.LabelSet{
|
||||||
@ -60,6 +59,22 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
values := []p.SamplePair{
|
||||||
|
{Value: 1, Timestamp: 1000},
|
||||||
|
{Value: 4, Timestamp: 4000},
|
||||||
|
{Value: 6, Timestamp: 7000},
|
||||||
|
{Value: 8, Timestamp: 1100},
|
||||||
|
}
|
||||||
|
rangeResult := queryResult{
|
||||||
|
Type: p.ValMatrix,
|
||||||
|
Result: p.Matrix{
|
||||||
|
&p.SampleStream{
|
||||||
|
Metric: p.Metric{"app": "Application", "tag2": "tag2"},
|
||||||
|
Values: values,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
tctx, err := setup()
|
tctx, err := setup()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -76,20 +91,20 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
RefID: "A",
|
RefID: "A",
|
||||||
JSON: b,
|
JSON: b,
|
||||||
}
|
}
|
||||||
res, err := execute(tctx, query, exemplars)
|
res, err := execute(tctx, query, exemplars, rangeResult)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Test fields
|
// Test fields
|
||||||
require.Len(t, res, 1)
|
require.Len(t, res, 2)
|
||||||
// require.Equal(t, res[0].Name, "exemplar")
|
require.Equal(t, res[0].Name, "exemplar")
|
||||||
require.Equal(t, res[0].Fields[0].Name, "Time")
|
require.Equal(t, res[0].Fields[0].Name, "Time")
|
||||||
require.Equal(t, res[0].Fields[1].Name, "Value")
|
require.Equal(t, res[0].Fields[1].Name, "Value")
|
||||||
require.Len(t, res[0].Fields, 6)
|
require.Len(t, res[0].Fields, 6)
|
||||||
|
|
||||||
// Test correct values (sampled to 2)
|
// Test correct values (sampled to 2)
|
||||||
require.Equal(t, res[0].Fields[1].Len(), 2)
|
require.Equal(t, res[0].Fields[1].Len(), 4)
|
||||||
require.Equal(t, res[0].Fields[1].At(0), 0.009545445)
|
require.Equal(t, res[0].Fields[1].At(0), 0.009545445)
|
||||||
require.Equal(t, res[0].Fields[1].At(1), 0.003535405)
|
require.Equal(t, res[0].Fields[1].At(3), 0.003535405)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("matrix response should be parsed normally", func(t *testing.T) {
|
t.Run("matrix response should be parsed normally", func(t *testing.T) {
|
||||||
@ -128,7 +143,7 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tctx, err := setup()
|
tctx, err := setup()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
res, err := execute(tctx, query, result)
|
res, err := execute(tctx, query, result, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, res, 1)
|
require.Len(t, res, 1)
|
||||||
@ -177,7 +192,7 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tctx, err := setup()
|
tctx, err := setup()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
res, err := execute(tctx, query, result)
|
res, err := execute(tctx, query, result, nil)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, res, 1)
|
require.Len(t, res, 1)
|
||||||
@ -222,7 +237,7 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tctx, err := setup()
|
tctx, err := setup()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
res, err := execute(tctx, query, result)
|
res, err := execute(tctx, query, result, nil)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, res, 1)
|
require.Len(t, res, 1)
|
||||||
@ -266,7 +281,7 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
|
|
||||||
tctx, err := setup()
|
tctx, err := setup()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
res, err := execute(tctx, query, result)
|
res, err := execute(tctx, query, result, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, `{app="Application"}`, res[0].Fields[1].Config.DisplayNameFromDS)
|
require.Equal(t, `{app="Application"}`, res[0].Fields[1].Config.DisplayNameFromDS)
|
||||||
@ -298,7 +313,7 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tctx, err := setup()
|
tctx, err := setup()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
res, err := execute(tctx, query, qr)
|
res, err := execute(tctx, query, qr, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, res, 1)
|
require.Len(t, res, 1)
|
||||||
@ -317,7 +332,6 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("scalar response should be parsed normally", func(t *testing.T) {
|
t.Run("scalar response should be parsed normally", func(t *testing.T) {
|
||||||
t.Skip("TODO: implement scalar responses")
|
|
||||||
qr := queryResult{
|
qr := queryResult{
|
||||||
Type: p.ValScalar,
|
Type: p.ValScalar,
|
||||||
Result: &p.Scalar{
|
Result: &p.Scalar{
|
||||||
@ -339,14 +353,15 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tctx, err := setup()
|
tctx, err := setup()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
res, err := execute(tctx, query, qr)
|
res, err := execute(tctx, query, qr, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, res, 1)
|
require.Len(t, res, 1)
|
||||||
require.Len(t, res[0].Fields, 2)
|
require.Len(t, res[0].Fields, 2)
|
||||||
require.Len(t, res[0].Fields[0].Labels, 0)
|
require.Len(t, res[0].Fields[0].Labels, 0)
|
||||||
require.Equal(t, res[0].Fields[0].Name, "Time")
|
require.Equal(t, res[0].Fields[0].Name, "Time")
|
||||||
require.Equal(t, "1", res[0].Fields[1].Name)
|
require.Equal(t, "Value", res[0].Fields[1].Name)
|
||||||
|
require.Equal(t, float64(1), res[0].Fields[1].At(0))
|
||||||
|
|
||||||
// Ensure the timestamps are UTC zoned
|
// Ensure the timestamps are UTC zoned
|
||||||
testValue := res[0].Fields[0].At(0)
|
testValue := res[0].Fields[0].At(0)
|
||||||
@ -360,22 +375,29 @@ type queryResult struct {
|
|||||||
Result any `json:"result"`
|
Result any `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeWithHeaders(tctx *testContext, query backend.DataQuery, qr any, headers map[string]string) (data.Frames, error) {
|
func executeWithHeaders(tctx *testContext, query backend.DataQuery, rqr any, eqr any, headers map[string]string) (data.Frames, error) {
|
||||||
req := backend.QueryDataRequest{
|
req := backend.QueryDataRequest{
|
||||||
Queries: []backend.DataQuery{query},
|
Queries: []backend.DataQuery{query},
|
||||||
Headers: headers,
|
Headers: headers,
|
||||||
}
|
}
|
||||||
|
|
||||||
promRes, err := toAPIResponse(qr)
|
rangeRes, err := toAPIResponse(rqr)
|
||||||
defer func() {
|
|
||||||
if err := promRes.Body.Close(); err != nil {
|
|
||||||
fmt.Println(fmt.Errorf("response body close error: %v", err))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tctx.httpProvider.setResponse(promRes)
|
exemplarRes, err := toAPIResponse(eqr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := rangeRes.Body.Close(); err != nil {
|
||||||
|
fmt.Println(fmt.Errorf("rangeRes body close error: %v", err))
|
||||||
|
}
|
||||||
|
if err := exemplarRes.Body.Close(); err != nil {
|
||||||
|
fmt.Println(fmt.Errorf("exemplarRes body close error: %v", err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
tctx.httpProvider.setResponse(rangeRes, exemplarRes)
|
||||||
|
|
||||||
res, err := tctx.queryData.Execute(context.Background(), &req)
|
res, err := tctx.queryData.Execute(context.Background(), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -385,8 +407,8 @@ func executeWithHeaders(tctx *testContext, query backend.DataQuery, qr any, head
|
|||||||
return res.Responses[req.Queries[0].RefID].Frames, nil
|
return res.Responses[req.Queries[0].RefID].Frames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func execute(tctx *testContext, query backend.DataQuery, qr any) (data.Frames, error) {
|
func execute(tctx *testContext, query backend.DataQuery, rqr any, eqr any) (data.Frames, error) {
|
||||||
return executeWithHeaders(tctx, query, qr, map[string]string{})
|
return executeWithHeaders(tctx, query, rqr, eqr, map[string]string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiResponse struct {
|
type apiResponse struct {
|
||||||
@ -426,7 +448,11 @@ func setup() (*testContext, error) {
|
|||||||
opts: httpclient.Options{
|
opts: httpclient.Options{
|
||||||
Timeouts: &httpclient.DefaultTimeoutOptions,
|
Timeouts: &httpclient.DefaultTimeoutOptions,
|
||||||
},
|
},
|
||||||
res: &http.Response{
|
rangeRes: &http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: io.NopCloser(bytes.NewReader([]byte(`{}`))),
|
||||||
|
},
|
||||||
|
exemplarRes: &http.Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: io.NopCloser(bytes.NewReader([]byte(`{}`))),
|
Body: io.NopCloser(bytes.NewReader([]byte(`{}`))),
|
||||||
},
|
},
|
||||||
@ -456,9 +482,10 @@ func setup() (*testContext, error) {
|
|||||||
|
|
||||||
type fakeHttpClientProvider struct {
|
type fakeHttpClientProvider struct {
|
||||||
httpclient.Provider
|
httpclient.Provider
|
||||||
opts httpclient.Options
|
opts httpclient.Options
|
||||||
req *http.Request
|
req *http.Request
|
||||||
res *http.Response
|
rangeRes *http.Response
|
||||||
|
exemplarRes *http.Response
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *fakeHttpClientProvider) New(opts ...httpclient.Options) (*http.Client, error) {
|
func (p *fakeHttpClientProvider) New(opts ...httpclient.Options) (*http.Client, error) {
|
||||||
@ -476,11 +503,18 @@ func (p *fakeHttpClientProvider) GetTransport(opts ...httpclient.Options) (http.
|
|||||||
return http.DefaultTransport, nil
|
return http.DefaultTransport, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *fakeHttpClientProvider) setResponse(res *http.Response) {
|
func (p *fakeHttpClientProvider) setResponse(rangeRes *http.Response, exemplarRes *http.Response) {
|
||||||
p.res = res
|
p.rangeRes = rangeRes
|
||||||
|
p.exemplarRes = exemplarRes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *fakeHttpClientProvider) RoundTrip(req *http.Request) (*http.Response, error) {
|
func (p *fakeHttpClientProvider) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
p.req = req
|
p.req = req
|
||||||
return p.res, nil
|
switch req.URL.Path {
|
||||||
|
case "/api/v1/query_range", "/api/v1/query":
|
||||||
|
return p.rangeRes, nil
|
||||||
|
case "/api/v1/query_exemplars":
|
||||||
|
return p.exemplarRes, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no such path: %s", req.URL.Path)
|
||||||
}
|
}
|
||||||
|
@ -83,15 +83,6 @@ func (r *Resource) Execute(ctx context.Context, req *backend.CallResourceRequest
|
|||||||
return callResponse, err
|
return callResponse, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resource) DetectVersion(ctx context.Context, req *backend.CallResourceRequest) (*backend.CallResourceResponse, error) {
|
|
||||||
newReq := &backend.CallResourceRequest{
|
|
||||||
PluginContext: req.PluginContext,
|
|
||||||
Path: "/api/v1/status/buildinfo",
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.Execute(ctx, newReq)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSelectors(expr string) ([]string, error) {
|
func getSelectors(expr string) ([]string, error) {
|
||||||
parsed, err := parser.ParseExpr(expr)
|
parsed, err := parser.ParseExpr(expr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
109
pkg/promlib/resource/resource_test.go
Normal file
109
pkg/promlib/resource/resource_test.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package resource_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
|
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/promlib/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockRoundTripper struct {
|
||||||
|
Response *http.Response
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
return m.Response, m.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
func setup() (*http.Client, backend.DataSourceInstanceSettings, log.Logger) {
|
||||||
|
// Mock HTTP Response
|
||||||
|
mockResponse := &http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: io.NopCloser(bytes.NewReader([]byte(`{"message": "success"}`))),
|
||||||
|
Header: make(http.Header),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a mock RoundTripper
|
||||||
|
mockTransport := &mockRoundTripper{
|
||||||
|
Response: mockResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a mock HTTP client using the mock RoundTripper
|
||||||
|
mockClient := &http.Client{
|
||||||
|
Transport: mockTransport,
|
||||||
|
}
|
||||||
|
|
||||||
|
settings := backend.DataSourceInstanceSettings{
|
||||||
|
ID: 1,
|
||||||
|
URL: "http://mock-server",
|
||||||
|
JSONData: []byte(`{}`),
|
||||||
|
}
|
||||||
|
|
||||||
|
logger := log.DefaultLogger
|
||||||
|
|
||||||
|
return mockClient, settings, logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewResource(t *testing.T) {
|
||||||
|
mockClient, settings, logger := setup()
|
||||||
|
res, err := resource.New(mockClient, settings, logger)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotNil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResource_Execute(t *testing.T) {
|
||||||
|
mockClient, settings, logger := setup()
|
||||||
|
res, err := resource.New(mockClient, settings, logger)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
req := &backend.CallResourceRequest{
|
||||||
|
URL: "/test",
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
resp, err := res.Execute(ctx, req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResource_GetSuggestions(t *testing.T) {
|
||||||
|
mockClient, _, logger := setup()
|
||||||
|
settings := backend.DataSourceInstanceSettings{
|
||||||
|
ID: 1,
|
||||||
|
URL: "http://localhost:9090",
|
||||||
|
JSONData: []byte(`{"httpMethod": "GET"}`),
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := resource.New(mockClient, settings, logger)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
suggestionReq := resource.SuggestionRequest{
|
||||||
|
LabelName: "instance",
|
||||||
|
Queries: []string{"up"},
|
||||||
|
Start: "1609459200",
|
||||||
|
End: "1609462800",
|
||||||
|
Limit: 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(suggestionReq)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
req := &backend.CallResourceRequest{
|
||||||
|
Body: body,
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
resp, err := res.GetSuggestions(ctx, req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
}
|
Reference in New Issue
Block a user