2024-07-23 01:08:30 +08:00
|
|
|
package test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"testing"
|
2024-07-31 08:39:33 +08:00
|
|
|
"time"
|
2024-07-23 01:08:30 +08:00
|
|
|
|
2025-01-24 21:03:23 +08:00
|
|
|
"github.com/go-jose/go-jose/v3/jwt"
|
2024-10-17 18:18:29 +08:00
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
2024-07-23 01:08:30 +08:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2025-01-24 21:03:23 +08:00
|
|
|
"github.com/grafana/authlib/authn"
|
|
|
|
"github.com/grafana/authlib/types"
|
2024-07-26 00:17:39 +08:00
|
|
|
"github.com/grafana/dskit/services"
|
2024-07-23 01:08:30 +08:00
|
|
|
infraDB "github.com/grafana/grafana/pkg/infra/db"
|
2024-10-28 20:35:30 +08:00
|
|
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
2024-07-23 01:08:30 +08:00
|
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2025-02-20 22:03:08 +08:00
|
|
|
"github.com/grafana/grafana/pkg/storage/unified"
|
2024-07-23 01:08:30 +08:00
|
|
|
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
|
|
|
"github.com/grafana/grafana/pkg/storage/unified/sql"
|
|
|
|
"github.com/grafana/grafana/pkg/storage/unified/sql/db/dbimpl"
|
2025-02-20 23:43:26 +08:00
|
|
|
unitest "github.com/grafana/grafana/pkg/storage/unified/testing"
|
2024-07-23 01:08:30 +08:00
|
|
|
"github.com/grafana/grafana/pkg/tests/testsuite"
|
|
|
|
"github.com/grafana/grafana/pkg/util/testutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
testsuite.Run(m)
|
|
|
|
}
|
|
|
|
|
2025-02-20 23:43:26 +08:00
|
|
|
// TestStorageBackend is a test for the StorageBackend interface.
|
|
|
|
func TestIntegrationSQLStorageBackend(t *testing.T) {
|
2025-03-18 21:37:11 +08:00
|
|
|
if infraDB.IsTestDBSpanner() {
|
|
|
|
t.Skip("skipping integration test")
|
|
|
|
}
|
|
|
|
|
2025-02-26 22:18:59 +08:00
|
|
|
t.Run("IsHA (polling notifier)", func(t *testing.T) {
|
|
|
|
unitest.RunStorageBackendTest(t, func(ctx context.Context) resource.StorageBackend {
|
|
|
|
dbstore := infraDB.InitTestDB(t)
|
|
|
|
eDB, err := dbimpl.ProvideResourceDB(dbstore, setting.NewCfg(), nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, eDB)
|
2025-01-28 22:17:52 +08:00
|
|
|
|
2025-02-26 22:18:59 +08:00
|
|
|
backend, err := sql.NewBackend(sql.BackendOptions{
|
|
|
|
DBProvider: eDB,
|
|
|
|
IsHA: true,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, backend)
|
|
|
|
err = backend.Init(testutil.NewDefaultTestContext(t))
|
|
|
|
require.NoError(t, err)
|
|
|
|
return backend
|
|
|
|
}, nil)
|
|
|
|
})
|
2025-02-21 19:25:35 +08:00
|
|
|
|
2025-02-26 22:18:59 +08:00
|
|
|
t.Run("NotHA (in process notifier)", func(t *testing.T) {
|
|
|
|
unitest.RunStorageBackendTest(t, func(ctx context.Context) resource.StorageBackend {
|
|
|
|
dbstore := infraDB.InitTestDB(t)
|
|
|
|
eDB, err := dbimpl.ProvideResourceDB(dbstore, setting.NewCfg(), nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, eDB)
|
|
|
|
|
|
|
|
backend, err := sql.NewBackend(sql.BackendOptions{
|
|
|
|
DBProvider: eDB,
|
|
|
|
IsHA: false,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, backend)
|
|
|
|
err = backend.Init(testutil.NewDefaultTestContext(t))
|
|
|
|
require.NoError(t, err)
|
|
|
|
return backend
|
|
|
|
}, nil)
|
|
|
|
})
|
2025-01-09 04:08:10 +08:00
|
|
|
}
|
|
|
|
|
2024-07-26 00:17:39 +08:00
|
|
|
func TestClientServer(t *testing.T) {
|
2024-10-11 17:11:33 +08:00
|
|
|
if infraDB.IsTestDbSQLite() {
|
|
|
|
t.Skip("TODO: test blocking, skipping to unblock Enterprise until we fix this")
|
|
|
|
}
|
2025-03-18 21:37:11 +08:00
|
|
|
if infraDB.IsTestDBSpanner() {
|
|
|
|
t.Skip("skipping integration test")
|
|
|
|
}
|
|
|
|
|
2024-07-31 08:39:33 +08:00
|
|
|
ctx := testutil.NewTestContext(t, time.Now().Add(5*time.Second))
|
2024-07-26 00:17:39 +08:00
|
|
|
dbstore := infraDB.InitTestDB(t)
|
|
|
|
|
|
|
|
cfg := setting.NewCfg()
|
2024-11-20 18:13:33 +08:00
|
|
|
cfg.GRPCServer.Address = "localhost:0" // get a free address
|
|
|
|
cfg.GRPCServer.Network = "tcp"
|
2024-07-26 00:17:39 +08:00
|
|
|
|
2024-08-22 00:28:30 +08:00
|
|
|
features := featuremgmt.WithFeatures()
|
2024-07-26 00:17:39 +08:00
|
|
|
|
2025-03-13 22:09:38 +08:00
|
|
|
svc, err := sql.ProvideUnifiedStorageGrpcService(cfg, features, dbstore, nil, prometheus.NewPedanticRegistry(), nil, nil, nil)
|
2024-07-26 00:17:39 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
var client resource.ResourceStoreClient
|
|
|
|
|
2025-01-24 21:03:23 +08:00
|
|
|
clientCtx := types.WithAuthInfo(context.Background(), authn.NewAccessTokenAuthInfo(authn.Claims[authn.AccessTokenClaims]{
|
|
|
|
Claims: jwt.Claims{
|
|
|
|
Subject: "testuser",
|
|
|
|
},
|
|
|
|
Rest: authn.AccessTokenClaims{},
|
|
|
|
}))
|
2024-07-26 00:17:39 +08:00
|
|
|
|
|
|
|
t.Run("Start and stop service", func(t *testing.T) {
|
|
|
|
err = services.StartAndAwaitRunning(ctx, svc)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotEmpty(t, svc.GetAddress())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Create a client", func(t *testing.T) {
|
2025-02-20 22:03:08 +08:00
|
|
|
conn, err := unified.GrpcConn(svc.GetAddress(), prometheus.NewPedanticRegistry())
|
2024-07-26 00:17:39 +08:00
|
|
|
require.NoError(t, err)
|
2025-02-26 16:22:09 +08:00
|
|
|
client, err = resource.NewRemoteResourceClient(tracing.NewNoopTracerService(), conn, resource.RemoteResourceClientConfig{
|
|
|
|
Token: "some-token",
|
|
|
|
TokenExchangeURL: "http://some-change-url",
|
|
|
|
AllowInsecure: true,
|
|
|
|
})
|
2024-10-24 15:12:37 +08:00
|
|
|
require.NoError(t, err)
|
2024-07-26 00:17:39 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Create a resource", func(t *testing.T) {
|
|
|
|
raw := []byte(`{
|
|
|
|
"apiVersion": "group/v0alpha1",
|
|
|
|
"kind": "resource",
|
|
|
|
"metadata": {
|
|
|
|
"name": "item1",
|
|
|
|
"namespace": "namespace"
|
|
|
|
},
|
|
|
|
"spec": {}
|
|
|
|
}`)
|
|
|
|
resp, err := client.Create(clientCtx, &resource.CreateRequest{
|
|
|
|
Key: resourceKey("item1"),
|
|
|
|
Value: raw,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Empty(t, resp.Error)
|
|
|
|
require.Greater(t, resp.ResourceVersion, int64(0))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Read the resource", func(t *testing.T) {
|
|
|
|
resp, err := client.Read(clientCtx, &resource.ReadRequest{
|
|
|
|
Key: resourceKey("item1"),
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Empty(t, resp.Error)
|
|
|
|
require.Greater(t, resp.ResourceVersion, int64(0))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Stop the service", func(t *testing.T) {
|
|
|
|
err = services.StopAndAwaitTerminated(ctx, svc)
|
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
2024-07-23 01:08:30 +08:00
|
|
|
|
|
|
|
func resourceKey(name string) *resource.ResourceKey {
|
|
|
|
return &resource.ResourceKey{
|
|
|
|
Namespace: "namespace",
|
|
|
|
Group: "group",
|
|
|
|
Resource: "resource",
|
|
|
|
Name: name,
|
|
|
|
}
|
|
|
|
}
|