mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 11:32:16 +08:00
184 lines
5.2 KiB
Go
184 lines
5.2 KiB
Go
package plugin
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
|
datav0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
|
|
"github.com/grafana/grafana/pkg/aggregator/apis/aggregation/v0alpha1"
|
|
"github.com/grafana/grafana/pkg/aggregator/apiserver/plugin/fakes"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestQueryDataHandler(t *testing.T) {
|
|
dps := v0alpha1.DataPlaneService{
|
|
Spec: v0alpha1.DataPlaneServiceSpec{
|
|
PluginID: "testds",
|
|
Group: "testds.example.com",
|
|
Version: "v1",
|
|
Services: []v0alpha1.Service{
|
|
{
|
|
Type: v0alpha1.QueryServiceType,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
pluginContext := backend.PluginContext{
|
|
DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{
|
|
ID: 1,
|
|
},
|
|
}
|
|
contextProvider := &fakes.FakePluginContextProvider{
|
|
PluginContext: pluginContext,
|
|
}
|
|
|
|
res := &backend.QueryDataResponse{
|
|
Responses: map[string]backend.DataResponse{
|
|
"A": {
|
|
Frames: []*data.Frame{
|
|
{
|
|
Name: "test-frame",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
pc := &fakes.FakePluginClient{
|
|
QueryDataHandlerFunc: newfakeQueryDataHandler(res, nil),
|
|
}
|
|
|
|
delegate := fakes.NewFakeHTTPHandler(http.StatusNotFound, []byte(`Not Found`))
|
|
handler := NewPluginHandler(pc, dps, contextProvider, delegate)
|
|
|
|
qdr := datav0alpha1.QueryDataRequest{
|
|
TimeRange: datav0alpha1.TimeRange{},
|
|
Queries: []datav0alpha1.DataQuery{{
|
|
CommonQueryProperties: datav0alpha1.CommonQueryProperties{
|
|
RefID: "1",
|
|
ResultAssertions: &datav0alpha1.ResultAssertions{},
|
|
TimeRange: &datav0alpha1.TimeRange{},
|
|
Datasource: &datav0alpha1.DataSourceRef{
|
|
Type: "testds",
|
|
UID: "123",
|
|
APIVersion: "v1",
|
|
},
|
|
DatasourceID: 0,
|
|
QueryType: "",
|
|
MaxDataPoints: 0,
|
|
IntervalMS: 0,
|
|
Hide: false,
|
|
},
|
|
}},
|
|
Debug: false,
|
|
}
|
|
|
|
t.Run("should return query response", func(t *testing.T) {
|
|
buf := bytes.NewBuffer(nil)
|
|
assert.NoError(t, json.NewEncoder(buf).Encode(qdr))
|
|
|
|
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/connections/123/query", buf)
|
|
assert.NoError(t, err)
|
|
|
|
rr := httptest.NewRecorder()
|
|
handler.ServeHTTP(rr, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
res := &v0alpha1.QueryDataResponse{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: "aggregation.grafana.com/v0alpha1",
|
|
Kind: "QueryDataResponse",
|
|
},
|
|
QueryDataResponse: *res,
|
|
}
|
|
resBuf := bytes.NewBuffer(nil)
|
|
assert.NoError(t, json.NewEncoder(resBuf).Encode(res))
|
|
expected, err := json.MarshalIndent(res, "", " ")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, string(expected), rr.Body.String())
|
|
})
|
|
|
|
t.Run("should return type error", func(t *testing.T) {
|
|
qdr.Queries[0].Datasource.Type = "wrongds"
|
|
buf := bytes.NewBuffer(nil)
|
|
assert.NoError(t, json.NewEncoder(buf).Encode(qdr))
|
|
|
|
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/connections/123/query", buf)
|
|
assert.NoError(t, err)
|
|
|
|
rr := httptest.NewRecorder()
|
|
handler.ServeHTTP(rr, req)
|
|
|
|
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
|
res := &metav1.Status{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: "v1",
|
|
Kind: "Status",
|
|
},
|
|
Status: metav1.StatusFailure,
|
|
Code: http.StatusInternalServerError,
|
|
Message: "invalid datasource type",
|
|
}
|
|
resBuf := bytes.NewBuffer(nil)
|
|
assert.NoError(t, json.NewEncoder(resBuf).Encode(res))
|
|
expected, err := json.MarshalIndent(res, "", " ")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, string(expected), rr.Body.String())
|
|
})
|
|
|
|
t.Run("should return UID error", func(t *testing.T) {
|
|
qdr.Queries[0].Datasource.Type = "testds"
|
|
buf := bytes.NewBuffer(nil)
|
|
assert.NoError(t, json.NewEncoder(buf).Encode(qdr))
|
|
|
|
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/connections/abc/query", buf)
|
|
assert.NoError(t, err)
|
|
|
|
rr := httptest.NewRecorder()
|
|
handler.ServeHTTP(rr, req)
|
|
|
|
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
|
res := &metav1.Status{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: "v1",
|
|
Kind: "Status",
|
|
},
|
|
Status: metav1.StatusFailure,
|
|
Code: http.StatusInternalServerError,
|
|
Message: "invalid datasource UID",
|
|
}
|
|
resBuf := bytes.NewBuffer(nil)
|
|
assert.NoError(t, json.NewEncoder(resBuf).Encode(res))
|
|
expected, err := json.MarshalIndent(res, "", " ")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, string(expected), rr.Body.String())
|
|
})
|
|
|
|
t.Run("should return delegate response if group does not match", func(t *testing.T) {
|
|
req, err := http.NewRequest("POST", "/apis/wrongds.example.com/v1/namespaces/default/connections/abc/query", bytes.NewBuffer(nil))
|
|
assert.NoError(t, err)
|
|
|
|
rr := httptest.NewRecorder()
|
|
handler.ServeHTTP(rr, req)
|
|
|
|
assert.Equal(t, http.StatusNotFound, rr.Code)
|
|
assert.Equal(t, "Not Found", rr.Body.String())
|
|
})
|
|
}
|
|
|
|
func newfakeQueryDataHandler(res *backend.QueryDataResponse, err error) backend.QueryDataHandlerFunc {
|
|
return func(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
|
return res, err
|
|
}
|
|
}
|