mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Revamp tests for Add/Update Datasource (#88386)
This commit is contained in:
parent
2d18de7e84
commit
0f32c2bff9
@ -3,7 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
@ -37,8 +38,7 @@ import (
|
|||||||
secretsmng "github.com/grafana/grafana/pkg/services/secrets/manager"
|
secretsmng "github.com/grafana/grafana/pkg/services/secrets/manager"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/tests/testsuite"
|
"github.com/grafana/grafana/pkg/tests/testsuite"
|
||||||
testdatasource "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource"
|
// testdatasource "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource"
|
||||||
"github.com/grafana/grafana/pkg/util/errutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -62,60 +62,183 @@ func (d *dataSourceMockRetriever) GetDataSource(ctx context.Context, query *data
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestService_AddDataSource(t *testing.T) {
|
func TestService_AddDataSource(t *testing.T) {
|
||||||
cfg := &setting.Cfg{}
|
t.Run("should not fail if the plugin is not installed", func(t *testing.T) {
|
||||||
|
dsService := initDSService(t)
|
||||||
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
|
PluginList: []pluginstore.Plugin{}, // empty list
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("should return validation error if command validation failed", func(t *testing.T) {
|
cmd := &datasources.AddDataSourceCommand{
|
||||||
dsplugin := &testdatasource.Service{}
|
OrgID: 1,
|
||||||
sqlStore := db.InitTestDB(t)
|
Type: datasources.DS_TESTDATA,
|
||||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
Name: "test",
|
||||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
}
|
||||||
quotaService := quotatest.New(false, nil)
|
|
||||||
mockPermission := acmock.NewMockedPermissionsService()
|
ds, err := dsService.AddDataSource(context.Background(), cmd)
|
||||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{
|
|
||||||
PluginList: []pluginstore.Plugin{{
|
|
||||||
JSONData: plugins.JSONData{
|
|
||||||
ID: "test",
|
|
||||||
Type: plugins.TypeDataSource,
|
|
||||||
Name: "test",
|
|
||||||
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callback will be executed
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
}, &pluginfakes.FakePluginClient{
|
|
||||||
ValidateAdmissionFunc: dsplugin.ValidateAdmission,
|
|
||||||
MutateAdmissionFunc: dsplugin.MutateAdmission,
|
|
||||||
ConvertObjectFunc: dsplugin.ConvertObject,
|
|
||||||
}, plugincontext.ProvideBaseService(cfg, pluginconfig.NewFakePluginRequestConfigProvider()))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "test", ds.Name)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("should fail if the datasource name is too long", func(t *testing.T) {
|
||||||
|
dsService := initDSService(t)
|
||||||
|
|
||||||
cmd := &datasources.AddDataSourceCommand{
|
cmd := &datasources.AddDataSourceCommand{
|
||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
Name: string(make([]byte, 256)),
|
Name: string(make([]byte, 256)),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = dsService.AddDataSource(context.Background(), cmd)
|
_, err := dsService.AddDataSource(context.Background(), cmd)
|
||||||
require.EqualError(t, err, "[datasource.nameInvalid] max length is 190")
|
require.EqualError(t, err, "[datasource.nameInvalid] max length is 190")
|
||||||
|
})
|
||||||
|
|
||||||
cmd = &datasources.AddDataSourceCommand{
|
t.Run("should fail if the datasource url is invalid", func(t *testing.T) {
|
||||||
|
dsService := initDSService(t)
|
||||||
|
|
||||||
|
cmd := &datasources.AddDataSourceCommand{
|
||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
URL: string(make([]byte, 256)),
|
URL: string(make([]byte, 256)),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = dsService.AddDataSource(context.Background(), cmd)
|
_, err := dsService.AddDataSource(context.Background(), cmd)
|
||||||
require.EqualError(t, err, "[datasource.urlInvalid] max length is 255")
|
require.EqualError(t, err, "[datasource.urlInvalid] max length is 255")
|
||||||
|
})
|
||||||
|
|
||||||
cmd = &datasources.AddDataSourceCommand{
|
t.Run("if a plugin has an API version defined (EXPERIMENTAL)", func(t *testing.T) {
|
||||||
OrgID: 1,
|
t.Run("should success to run admission hooks", func(t *testing.T) {
|
||||||
Type: "test", // required to validate apiserver
|
dsService := initDSService(t)
|
||||||
Name: "test",
|
validateExecuted := false
|
||||||
APIVersion: "v123", // invalid apiVersion
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
}
|
PluginList: []pluginstore.Plugin{{
|
||||||
|
JSONData: plugins.JSONData{
|
||||||
|
ID: "test",
|
||||||
|
Type: plugins.TypeDataSource,
|
||||||
|
Name: "test",
|
||||||
|
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callbacks will be executed
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
dsService.pluginClient = &pluginfakes.FakePluginClient{
|
||||||
|
ValidateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||||
|
validateExecuted = true
|
||||||
|
return &backend.ValidationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
MutateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||||
|
return &backend.MutationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
ObjectBytes: req.ObjectBytes,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
ConvertObjectFunc: func(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd := &datasources.AddDataSourceCommand{
|
||||||
|
OrgID: 1,
|
||||||
|
Type: "test", // required to validate apiserver
|
||||||
|
Name: "test",
|
||||||
|
APIVersion: "v0alpha1",
|
||||||
|
}
|
||||||
|
_, err := dsService.AddDataSource(context.Background(), cmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, validateExecuted)
|
||||||
|
})
|
||||||
|
|
||||||
_, err = dsService.AddDataSource(context.Background(), cmd)
|
t.Run("should fail at validation", func(t *testing.T) {
|
||||||
|
dsService := initDSService(t)
|
||||||
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
|
PluginList: []pluginstore.Plugin{{
|
||||||
|
JSONData: plugins.JSONData{
|
||||||
|
ID: "test",
|
||||||
|
Type: plugins.TypeDataSource,
|
||||||
|
Name: "test",
|
||||||
|
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callbacks will be executed
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
dsService.pluginClient = &pluginfakes.FakePluginClient{
|
||||||
|
ValidateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||||
|
settings, err := backend.DataSourceInstanceSettingsFromProto(req.ObjectBytes, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if settings.APIVersion != "v0alpha1" {
|
||||||
|
return &backend.ValidationResponse{
|
||||||
|
Allowed: false,
|
||||||
|
Result: &backend.StatusResult{
|
||||||
|
Status: "Failure",
|
||||||
|
Message: fmt.Sprintf("expected apiVersion: v0alpha1, found: %s", settings.APIVersion),
|
||||||
|
Reason: "badRequest",
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return &backend.ValidationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
MutateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
},
|
||||||
|
ConvertObjectFunc: func(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd := &datasources.AddDataSourceCommand{
|
||||||
|
OrgID: 1,
|
||||||
|
Type: "test", // required to validate apiserver
|
||||||
|
Name: "test",
|
||||||
|
APIVersion: "v123", // invalid apiVersion
|
||||||
|
}
|
||||||
|
_, err := dsService.AddDataSource(context.Background(), cmd)
|
||||||
|
assert.ErrorContains(t, err, "expected apiVersion: v0alpha1, found: v123")
|
||||||
|
})
|
||||||
|
|
||||||
var gErr errutil.Error
|
t.Run("should mutate a request", func(t *testing.T) {
|
||||||
require.True(t, errors.As(err, &gErr))
|
dsService := initDSService(t)
|
||||||
require.Equal(t, "expected apiVersion: v0alpha1, found: v123", gErr.PublicMessage)
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
require.Equal(t, 400, gErr.Public().StatusCode)
|
PluginList: []pluginstore.Plugin{{
|
||||||
|
JSONData: plugins.JSONData{
|
||||||
|
ID: "test",
|
||||||
|
Type: plugins.TypeDataSource,
|
||||||
|
Name: "test",
|
||||||
|
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callbacks will be executed
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
dsService.pluginClient = &pluginfakes.FakePluginClient{
|
||||||
|
ValidateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||||
|
return &backend.ValidationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
MutateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||||
|
settings, err := backend.DataSourceInstanceSettingsFromProto(req.ObjectBytes, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
settings.URL = "url-mutated"
|
||||||
|
pb, err := backend.DataSourceInstanceSettingsToProtoBytes(settings)
|
||||||
|
return &backend.MutationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
ObjectBytes: pb,
|
||||||
|
}, err
|
||||||
|
},
|
||||||
|
ConvertObjectFunc: func(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd := &datasources.AddDataSourceCommand{
|
||||||
|
OrgID: 1,
|
||||||
|
Type: "test", // required to validate apiserver
|
||||||
|
Name: "test",
|
||||||
|
APIVersion: "v0alpha1",
|
||||||
|
}
|
||||||
|
ds, err := dsService.AddDataSource(context.Background(), cmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "url-mutated", ds.URL)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,16 +322,8 @@ func TestService_getAvailableName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestService_UpdateDataSource(t *testing.T) {
|
func TestService_UpdateDataSource(t *testing.T) {
|
||||||
cfg := &setting.Cfg{}
|
|
||||||
|
|
||||||
t.Run("should return not found error if datasource not found", func(t *testing.T) {
|
t.Run("should return not found error if datasource not found", func(t *testing.T) {
|
||||||
sqlStore := db.InitTestDB(t)
|
dsService := initDSService(t)
|
||||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
|
||||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
|
||||||
quotaService := quotatest.New(false, nil)
|
|
||||||
mockPermission := acmock.NewMockedPermissionsService()
|
|
||||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{}, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cmd := &datasources.UpdateDataSourceCommand{
|
cmd := &datasources.UpdateDataSourceCommand{
|
||||||
UID: uuid.New().String(),
|
UID: uuid.New().String(),
|
||||||
@ -216,29 +331,12 @@ func TestService_UpdateDataSource(t *testing.T) {
|
|||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = dsService.UpdateDataSource(context.Background(), cmd)
|
_, err := dsService.UpdateDataSource(context.Background(), cmd)
|
||||||
require.ErrorIs(t, err, datasources.ErrDataSourceNotFound)
|
require.ErrorIs(t, err, datasources.ErrDataSourceNotFound)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should return validation error if command validation failed", func(t *testing.T) {
|
t.Run("should return validation error if command validation failed", func(t *testing.T) {
|
||||||
sqlStore := db.InitTestDB(t)
|
dsService := initDSService(t)
|
||||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
|
||||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
|
||||||
quotaService := quotatest.New(false, nil)
|
|
||||||
mockPermission := acmock.NewMockedPermissionsService()
|
|
||||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
|
||||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService,
|
|
||||||
&pluginstore.FakePluginStore{
|
|
||||||
PluginList: []pluginstore.Plugin{
|
|
||||||
{
|
|
||||||
JSONData: plugins.JSONData{
|
|
||||||
ID: "test",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, &pluginfakes.FakePluginClient{},
|
|
||||||
plugincontext.ProvideBaseService(cfg, pluginconfig.NewFakePluginRequestConfigProvider()))
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// First add the datasource
|
// First add the datasource
|
||||||
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||||
@ -271,15 +369,7 @@ func TestService_UpdateDataSource(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should return no error if updated datasource", func(t *testing.T) {
|
t.Run("should return no error if updated datasource", func(t *testing.T) {
|
||||||
sqlStore := db.InitTestDB(t)
|
dsService := initDSService(t)
|
||||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
|
||||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
|
||||||
quotaService := quotatest.New(false, nil)
|
|
||||||
mockPermission := acmock.NewMockedPermissionsService()
|
|
||||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{}, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
|
||||||
|
|
||||||
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
@ -298,15 +388,7 @@ func TestService_UpdateDataSource(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should return error if datasource with same name exist", func(t *testing.T) {
|
t.Run("should return error if datasource with same name exist", func(t *testing.T) {
|
||||||
sqlStore := db.InitTestDB(t)
|
dsService := initDSService(t)
|
||||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
|
||||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
|
||||||
quotaService := quotatest.New(false, nil)
|
|
||||||
mockPermission := acmock.NewMockedPermissionsService()
|
|
||||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{}, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
|
||||||
|
|
||||||
dsToUpdate, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
dsToUpdate, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
@ -331,15 +413,7 @@ func TestService_UpdateDataSource(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should merge cmd.SecureJsonData with db data", func(t *testing.T) {
|
t.Run("should merge cmd.SecureJsonData with db data", func(t *testing.T) {
|
||||||
sqlStore := db.InitTestDB(t)
|
dsService := initDSService(t)
|
||||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
|
||||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
|
||||||
quotaService := quotatest.New(false, nil)
|
|
||||||
mockPermission := acmock.NewMockedPermissionsService()
|
|
||||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{}, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
|
||||||
|
|
||||||
expectedDbKey := "db-secure-key"
|
expectedDbKey := "db-secure-key"
|
||||||
expectedDbValue := "db-secure-value"
|
expectedDbValue := "db-secure-value"
|
||||||
@ -375,16 +449,7 @@ func TestService_UpdateDataSource(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should preserve cmd.SecureJsonData when cmd.IgnoreOldSecureJsonData=true", func(t *testing.T) {
|
t.Run("should preserve cmd.SecureJsonData when cmd.IgnoreOldSecureJsonData=true", func(t *testing.T) {
|
||||||
sqlStore := db.InitTestDB(t)
|
dsService := initDSService(t)
|
||||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
|
||||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
|
||||||
quotaService := quotatest.New(false, nil)
|
|
||||||
mockPermission := acmock.NewMockedPermissionsService()
|
|
||||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{},
|
|
||||||
mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{}, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
|
||||||
|
|
||||||
notExpectedDbKey := "db-secure-key"
|
notExpectedDbKey := "db-secure-key"
|
||||||
dbValue := "db-secure-value"
|
dbValue := "db-secure-value"
|
||||||
@ -420,6 +485,61 @@ func TestService_UpdateDataSource(t *testing.T) {
|
|||||||
_, ok := secret[notExpectedDbKey]
|
_, ok := secret[notExpectedDbKey]
|
||||||
assert.False(t, ok)
|
assert.False(t, ok)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("should run validation and mutation hooks", func(t *testing.T) {
|
||||||
|
dsService := initDSService(t)
|
||||||
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
|
PluginList: []pluginstore.Plugin{{
|
||||||
|
JSONData: plugins.JSONData{
|
||||||
|
ID: "test",
|
||||||
|
Type: plugins.TypeDataSource,
|
||||||
|
Name: "test",
|
||||||
|
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callbacks will be executed
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
validateExecuted := false
|
||||||
|
mutateExecuted := false
|
||||||
|
dsService.pluginClient = &pluginfakes.FakePluginClient{
|
||||||
|
ValidateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||||
|
validateExecuted = true
|
||||||
|
return &backend.ValidationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
MutateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||||
|
mutateExecuted = true
|
||||||
|
return &backend.MutationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
ObjectBytes: req.ObjectBytes,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
ConvertObjectFunc: func(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||||
|
OrgID: 1,
|
||||||
|
Name: "test-datasource",
|
||||||
|
APIVersion: "v0alpha1",
|
||||||
|
Type: "test",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
cmd := &datasources.UpdateDataSourceCommand{
|
||||||
|
ID: ds.ID,
|
||||||
|
OrgID: ds.OrgID,
|
||||||
|
Name: "test-datasource-updated",
|
||||||
|
APIVersion: "v0alpha1",
|
||||||
|
Type: "test",
|
||||||
|
}
|
||||||
|
|
||||||
|
dsUpdated, err := dsService.UpdateDataSource(context.Background(), cmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, validateExecuted)
|
||||||
|
require.True(t, mutateExecuted)
|
||||||
|
require.Equal(t, "test-datasource-updated", dsUpdated.Name)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestService_NameScopeResolver(t *testing.T) {
|
func TestService_NameScopeResolver(t *testing.T) {
|
||||||
@ -1291,6 +1411,43 @@ func TestDataSource_CustomHeaders(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initDSService(t *testing.T) *Service {
|
||||||
|
cfg := &setting.Cfg{}
|
||||||
|
sqlStore := db.InitTestDB(t)
|
||||||
|
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
|
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||||
|
quotaService := quotatest.New(false, nil)
|
||||||
|
mockPermission := acmock.NewMockedPermissionsService()
|
||||||
|
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||||
|
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{
|
||||||
|
PluginList: []pluginstore.Plugin{{
|
||||||
|
JSONData: plugins.JSONData{
|
||||||
|
ID: "test",
|
||||||
|
Type: plugins.TypeDataSource,
|
||||||
|
Name: "test",
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}, &pluginfakes.FakePluginClient{
|
||||||
|
ValidateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||||
|
return &backend.ValidationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
MutateAdmissionFunc: func(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||||
|
return &backend.MutationResponse{
|
||||||
|
Allowed: true,
|
||||||
|
ObjectBytes: req.ObjectBytes,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
ConvertObjectFunc: func(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
},
|
||||||
|
}, plugincontext.ProvideBaseService(cfg, pluginconfig.NewFakePluginRequestConfigProvider()))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return dsService
|
||||||
|
}
|
||||||
|
|
||||||
const caCert string = `-----BEGIN CERTIFICATE-----
|
const caCert string = `-----BEGIN CERTIFICATE-----
|
||||||
MIIDATCCAemgAwIBAgIJAMQ5hC3CPDTeMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
|
MIIDATCCAemgAwIBAgIJAMQ5hC3CPDTeMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
|
||||||
BAMMDGNhLWs4cy1zdGhsbTAeFw0xNjEwMjcwODQyMjdaFw00NDAzMTQwODQyMjda
|
BAMMDGNhLWs4cy1zdGhsbTAeFw0xNjEwMjcwODQyMjdaFw00NDAzMTQwODQyMjda
|
||||||
|
Loading…
Reference in New Issue
Block a user