grafana/pkg/services/dashboardsnapshots/database/database_test.go

230 lines
7.5 KiB
Go

package database
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
dashboardsnapshot "github.com/grafana/grafana/pkg/apis/dashboardsnapshot/v0alpha1"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tests/testsuite"
)
func TestMain(m *testing.M) {
testsuite.Run(m)
}
func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
sqlstore := db.InitTestDB(t)
cfg := setting.NewCfg()
dashStore := ProvideStore(sqlstore, cfg)
origSecret := cfg.SecretKey
cfg.SecretKey = "dashboard_snapshot_testing"
t.Cleanup(func() {
cfg.SecretKey = origSecret
})
secretsService := fakes.NewFakeSecretsService()
dashboard := simplejson.NewFromAny(map[string]any{"hello": "mupp"})
t.Run("Given saved snapshot", func(t *testing.T) {
rawDashboard, err := dashboard.Encode()
require.NoError(t, err)
encryptedDashboard, err := secretsService.Encrypt(context.Background(), rawDashboard, secrets.WithoutScope())
require.NoError(t, err)
cmd := dashboardsnapshots.CreateDashboardSnapshotCommand{
Key: "hej",
DashboardEncrypted: encryptedDashboard,
UserID: 1000,
OrgID: 1,
}
result, err := dashStore.CreateDashboardSnapshot(context.Background(), &cmd)
require.NoError(t, err)
t.Run("Should be able to get snapshot by key", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotQuery{Key: "hej"}
queryResult, err := dashStore.GetDashboardSnapshot(context.Background(), &query)
require.NoError(t, err)
assert.NotNil(t, queryResult)
decryptedDashboard, err := secretsService.Decrypt(
context.Background(),
queryResult.DashboardEncrypted,
)
require.NoError(t, err)
dashboard, err := simplejson.NewJson(decryptedDashboard)
require.NoError(t, err)
assert.Equal(t, "mupp", dashboard.Get("hello").MustString())
})
t.Run("And the user has the admin role", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgID: 1,
SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin, UserID: 1000, OrgID: 1},
}
queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
t.Run("Should return all the snapshots", func(t *testing.T) {
assert.NotNil(t, queryResult)
assert.Len(t, queryResult, 1)
})
})
t.Run("And the user has the editor role and has created a snapshot", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgID: 1,
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, UserID: 1000},
}
queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
t.Run("Should return all the snapshots", func(t *testing.T) {
require.NotNil(t, queryResult)
assert.Len(t, queryResult, 1)
})
})
t.Run("And the user has the editor role and has not created any snapshot", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgID: 1,
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, UserID: 2},
}
queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
t.Run("Should not return any snapshots", func(t *testing.T) {
require.NotNil(t, queryResult)
assert.Empty(t, queryResult)
})
})
t.Run("And the user is anonymous", func(t *testing.T) {
cmd := dashboardsnapshots.CreateDashboardSnapshotCommand{
Key: "strangesnapshotwithuserid0",
DeleteKey: "adeletekey",
DashboardCreateCommand: dashboardsnapshot.DashboardCreateCommand{
Dashboard: &common.Unstructured{Object: map[string]any{
"hello": "mupp",
}},
},
UserID: 0,
OrgID: 1,
}
_, err := dashStore.CreateDashboardSnapshot(context.Background(), &cmd)
require.NoError(t, err)
t.Run("Should not return any snapshots", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgID: 1,
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, IsAnonymous: true, UserID: 0},
}
queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
require.NotNil(t, queryResult)
assert.Empty(t, queryResult)
})
})
t.Run("Should have encrypted dashboard data", func(t *testing.T) {
decryptedDashboard, err := secretsService.Decrypt(
context.Background(),
result.DashboardEncrypted,
)
require.NoError(t, err)
require.Equal(t, decryptedDashboard, rawDashboard)
})
})
}
func TestIntegrationDeleteExpiredSnapshots(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
sqlstore := db.InitTestDB(t)
dashStore := NewStore(sqlstore, false)
t.Run("Testing dashboard snapshots clean up", func(t *testing.T) {
nonExpiredSnapshot := createTestSnapshot(t, dashStore, "key1", 48000)
createTestSnapshot(t, dashStore, "key2", -1200)
createTestSnapshot(t, dashStore, "key3", -1200)
err := dashStore.DeleteExpiredSnapshots(context.Background(), &dashboardsnapshots.DeleteExpiredSnapshotsCommand{})
require.NoError(t, err)
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgID: 1,
SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin, UserID: 1000, OrgID: 1},
}
queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
assert.Len(t, queryResult, 1)
assert.Equal(t, nonExpiredSnapshot.Key, queryResult[0].Key)
err = dashStore.DeleteExpiredSnapshots(context.Background(), &dashboardsnapshots.DeleteExpiredSnapshotsCommand{})
require.NoError(t, err)
query = dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgID: 1,
SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin, UserID: 1000, OrgID: 1},
}
queryResult, err = dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
require.Len(t, queryResult, 1)
require.Equal(t, nonExpiredSnapshot.Key, queryResult[0].Key)
})
}
func createTestSnapshot(t *testing.T, dashStore *DashboardSnapshotStore, key string, expires int64) *dashboardsnapshots.DashboardSnapshot {
cmd := dashboardsnapshots.CreateDashboardSnapshotCommand{
Key: key,
DeleteKey: "delete" + key,
DashboardCreateCommand: dashboardsnapshot.DashboardCreateCommand{
Expires: expires,
Dashboard: &common.Unstructured{Object: map[string]any{
"hello": "mupp",
}},
},
UserID: 1000,
OrgID: 1,
}
result, err := dashStore.CreateDashboardSnapshot(context.Background(), &cmd)
require.NoError(t, err)
// Set expiry date manually - to be able to create expired snapshots
if expires < 0 {
expireDate := time.Now().Add(time.Second * time.Duration(expires))
err = dashStore.store.WithDbSession(context.Background(), func(sess *db.Session) error {
_, err := sess.Exec("UPDATE dashboard_snapshot SET expires = ? WHERE id = ?", expireDate, result.ID)
return err
})
require.NoError(t, err)
}
return result
}