* Integrate mt querier with query caching * typo * let the caller set cache status response header * fix TestQueryAPI * make gen-go * handle CachingServiceClient being nil and make gen-go * include namespace in cache key * set signed in user namespace in query_test.go * fix test * remove commented out code * undo services/query/query.go changes * make gen-go * remove namespace requirement * fix tests * fix test * remove namespace from SignedInUser in tests * make gen-go
131 lines
4.4 KiB
Go
131 lines
4.4 KiB
Go
package caching
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
|
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
|
"github.com/grafana/grafana/pkg/web"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestWithQueryDataCaching(t *testing.T) {
|
|
t.Run("caching is a no-op when service is nil", func(t *testing.T) {
|
|
var s *CachingServiceClient
|
|
req := backend.QueryDataRequest{}
|
|
fakeResponse := &backend.QueryDataResponse{}
|
|
response, err := s.WithQueryDataCaching(t.Context(), &req, func() (*backend.QueryDataResponse, error) {
|
|
return fakeResponse, nil
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, fakeResponse, response)
|
|
})
|
|
|
|
t.Run("cache status is included in the response if a request context is available", func(t *testing.T) {
|
|
fakeCachingService := NewFakeOSSCachingService()
|
|
fakeCachingService.ReturnStatus = StatusMiss
|
|
client := ProvideCachingServiceClient(fakeCachingService, nil)
|
|
|
|
req := backend.QueryDataRequest{}
|
|
|
|
reqCtx := &contextmodel.ReqContext{
|
|
Context: &web.Context{
|
|
Resp: web.NewResponseWriter("", httptest.NewRecorder()),
|
|
},
|
|
}
|
|
ctx := context.WithValue(t.Context(), ctxkey.Key{}, reqCtx)
|
|
fakeResponse := &backend.QueryDataResponse{}
|
|
response, err := client.WithQueryDataCaching(ctx, &req, func() (*backend.QueryDataResponse, error) {
|
|
return fakeResponse, nil
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, fakeResponse, response)
|
|
require.EqualValues(t, StatusMiss, reqCtx.Resp.Header().Get(XCacheHeader))
|
|
})
|
|
|
|
t.Run("caching can be used without a request context", func(t *testing.T) {
|
|
fakeCachingService := NewFakeOSSCachingService()
|
|
fakeCachingService.ReturnStatus = StatusMiss
|
|
client := ProvideCachingServiceClient(fakeCachingService, nil)
|
|
|
|
req := backend.QueryDataRequest{}
|
|
|
|
fakeResponse := &backend.QueryDataResponse{}
|
|
// Using the default test context, no request context.
|
|
response, err := client.WithQueryDataCaching(t.Context(), &req, func() (*backend.QueryDataResponse, error) {
|
|
return fakeResponse, nil
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, fakeResponse, response)
|
|
})
|
|
}
|
|
|
|
func TestWithCallResourceCaching(t *testing.T) {
|
|
t.Run("caching is a no-op when service is nil", func(t *testing.T) {
|
|
var s *CachingServiceClient
|
|
req := backend.CallResourceRequest{}
|
|
fakeErr := errors.New("oops")
|
|
err := s.WithCallResourceCaching(t.Context(), &req, nil, func(backend.CallResourceResponseSender) error {
|
|
return fakeErr
|
|
})
|
|
require.ErrorIs(t, err, fakeErr)
|
|
})
|
|
|
|
t.Run("cache status is included in the response if a request context is available", func(t *testing.T) {
|
|
fakeCachingService := NewFakeOSSCachingService()
|
|
fakeCachingService.ReturnStatus = StatusMiss
|
|
client := ProvideCachingServiceClient(fakeCachingService, nil)
|
|
|
|
req := backend.CallResourceRequest{}
|
|
|
|
reqCtx := &contextmodel.ReqContext{
|
|
Context: &web.Context{
|
|
Resp: web.NewResponseWriter("", httptest.NewRecorder()),
|
|
},
|
|
}
|
|
ctx := context.WithValue(t.Context(), ctxkey.Key{}, reqCtx)
|
|
sender := func(*backend.CallResourceResponse) error {
|
|
return nil
|
|
}
|
|
var fakeErr = errors.New("oops")
|
|
err := client.WithCallResourceCaching(ctx, &req, backend.CallResourceResponseSenderFunc(sender), func(backend.CallResourceResponseSender) error {
|
|
return fakeErr
|
|
})
|
|
require.ErrorIs(t, err, fakeErr)
|
|
require.EqualValues(t, StatusMiss, reqCtx.Resp.Header().Get(XCacheHeader))
|
|
})
|
|
|
|
t.Run("caching can be used without a request context", func(t *testing.T) {
|
|
fakeCachingService := NewFakeOSSCachingService()
|
|
fakeCachingService.ReturnStatus = StatusMiss
|
|
client := ProvideCachingServiceClient(fakeCachingService, nil)
|
|
|
|
req := backend.CallResourceRequest{}
|
|
|
|
sender := func(*backend.CallResourceResponse) error {
|
|
return nil
|
|
}
|
|
var fakeErr = errors.New("oops")
|
|
// Using the default test context, no request context.
|
|
err := client.WithCallResourceCaching(t.Context(), &req, backend.CallResourceResponseSenderFunc(sender), func(_ backend.CallResourceResponseSender) error {
|
|
return fakeErr
|
|
})
|
|
require.ErrorIs(t, err, fakeErr)
|
|
})
|
|
}
|
|
|
|
func TestGetDatasourceType(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
require.Equal(t, "unknown", getDatasourceType(backend.PluginContext{}))
|
|
require.Equal(t, "name", getDatasourceType(backend.PluginContext{
|
|
DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{
|
|
Name: "name",
|
|
},
|
|
}))
|
|
}
|