2024-01-10 04:26:24 +08:00
|
|
|
package dashboards
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2025-08-29 22:46:39 +08:00
|
|
|
"encoding/json"
|
2024-09-25 21:10:19 +08:00
|
|
|
"fmt"
|
2024-01-10 04:26:24 +08:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
2025-08-29 22:46:39 +08:00
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
2024-01-10 04:26:24 +08:00
|
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
|
|
|
2025-08-29 22:46:39 +08:00
|
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
2024-01-10 04:26:24 +08:00
|
|
|
"github.com/grafana/grafana/pkg/services/datasources"
|
|
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
|
|
"github.com/grafana/grafana/pkg/tests/apis"
|
|
|
|
"github.com/grafana/grafana/pkg/tests/testinfra"
|
2024-03-01 06:58:49 +08:00
|
|
|
"github.com/grafana/grafana/pkg/tests/testsuite"
|
2025-09-08 21:49:49 +08:00
|
|
|
"github.com/grafana/grafana/pkg/util/testutil"
|
2024-01-10 04:26:24 +08:00
|
|
|
)
|
|
|
|
|
2024-03-01 06:58:49 +08:00
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
testsuite.Run(m)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestIntegrationTestDatasource(t *testing.T) {
|
2025-09-08 21:49:49 +08:00
|
|
|
testutil.SkipIntegrationTestInShortMode(t)
|
|
|
|
|
2024-01-10 04:26:24 +08:00
|
|
|
helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
|
|
|
AppModeProduction: false, // dev mode required for datasource connections
|
|
|
|
DisableAnonymous: true,
|
|
|
|
EnableFeatureToggles: []string{
|
|
|
|
featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs, // Required to start the example service
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
// Create a single datasource
|
|
|
|
ds := helper.CreateDS(&datasources.AddDataSourceCommand{
|
|
|
|
Name: "test",
|
|
|
|
Type: datasources.DS_TESTDATA,
|
|
|
|
UID: "test",
|
|
|
|
OrgID: int64(1),
|
2025-08-29 22:46:39 +08:00
|
|
|
|
|
|
|
// These settings are not actually used, but testing that they get saved
|
|
|
|
Database: "testdb",
|
|
|
|
URL: "http://fake.url",
|
|
|
|
Access: datasources.DS_ACCESS_PROXY,
|
|
|
|
User: "example",
|
|
|
|
ReadOnly: true,
|
|
|
|
JsonData: simplejson.NewFromAny(map[string]any{
|
|
|
|
"hello": "world",
|
|
|
|
}),
|
|
|
|
SecureJsonData: map[string]string{
|
|
|
|
"aaa": "AAA",
|
|
|
|
"bbb": "BBB",
|
|
|
|
},
|
2024-01-10 04:26:24 +08:00
|
|
|
})
|
|
|
|
require.Equal(t, "test", ds.UID)
|
|
|
|
|
2025-08-29 22:46:39 +08:00
|
|
|
t.Run("Admin configs", func(t *testing.T) {
|
|
|
|
client := helper.Org1.Admin.ResourceClient(t, schema.GroupVersionResource{
|
|
|
|
Group: "testdata.datasource.grafana.app",
|
|
|
|
Version: "v0alpha1",
|
|
|
|
Resource: "datasources",
|
|
|
|
}).Namespace("default")
|
|
|
|
ctx := context.Background()
|
2024-01-10 04:26:24 +08:00
|
|
|
|
2025-08-29 22:46:39 +08:00
|
|
|
list, err := client.List(ctx, metav1.ListOptions{})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, list.Items, 1, "expected a single connection")
|
|
|
|
require.Equal(t, "test", list.Items[0].GetName(), "with the test uid")
|
|
|
|
|
|
|
|
spec, _, _ := unstructured.NestedMap(list.Items[0].Object, "spec")
|
|
|
|
jj, _ := json.MarshalIndent(spec, "", " ")
|
|
|
|
fmt.Printf("%s\n", string(jj))
|
|
|
|
require.JSONEq(t, `{
|
|
|
|
"access": "proxy",
|
|
|
|
"database": "testdb",
|
|
|
|
"isDefault": true,
|
|
|
|
"jsonData": {
|
|
|
|
"hello": "world"
|
|
|
|
},
|
|
|
|
"readOnly": true,
|
|
|
|
"title": "test",
|
|
|
|
"url": "http://fake.url",
|
|
|
|
"user": "example"
|
|
|
|
}`, string(jj))
|
2024-01-10 04:26:24 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Call subresources", func(t *testing.T) {
|
2024-02-01 02:36:51 +08:00
|
|
|
client := helper.Org1.Admin.ResourceClient(t, schema.GroupVersionResource{
|
2024-01-10 04:26:24 +08:00
|
|
|
Group: "testdata.datasource.grafana.app",
|
|
|
|
Version: "v0alpha1",
|
2025-08-29 22:46:39 +08:00
|
|
|
Resource: "datasources",
|
2024-01-10 04:26:24 +08:00
|
|
|
}).Namespace("default")
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
list, err := client.List(ctx, metav1.ListOptions{})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, list.Items, 1, "expected a single connection")
|
|
|
|
require.Equal(t, "test", list.Items[0].GetName(), "with the test uid")
|
|
|
|
|
|
|
|
rsp, err := client.Get(ctx, "test", metav1.GetOptions{}, "health")
|
|
|
|
require.NoError(t, err)
|
|
|
|
body, err := rsp.MarshalJSON()
|
|
|
|
require.NoError(t, err)
|
|
|
|
//fmt.Printf("GOT: %v\n", string(body))
|
|
|
|
require.JSONEq(t, `{
|
|
|
|
"apiVersion": "testdata.datasource.grafana.app/v0alpha1",
|
|
|
|
"code": 1,
|
|
|
|
"kind": "HealthCheckResult",
|
|
|
|
"message": "Data source is working",
|
|
|
|
"status": "OK"
|
|
|
|
}
|
|
|
|
`, string(body))
|
|
|
|
|
|
|
|
// Test connecting to non-JSON marshaled data
|
|
|
|
raw := apis.DoRequest[any](helper, apis.RequestParams{
|
|
|
|
User: helper.Org1.Admin,
|
|
|
|
Method: "GET",
|
2025-08-29 22:46:39 +08:00
|
|
|
Path: "/apis/testdata.datasource.grafana.app/v0alpha1/namespaces/default/datasources/test/resource",
|
2024-01-10 04:26:24 +08:00
|
|
|
}, nil)
|
|
|
|
require.Equal(t, `Hello world from test datasource!`, string(raw.Body))
|
|
|
|
})
|
|
|
|
}
|