This commit fixes the following golint warnings: pkg/api/avatar/avatar.go:229:12: should omit type *http.Client from declaration of var client; it will be inferred from the right-hand side pkg/login/brute_force_login_protection.go:13:26: should omit type time.Duration from declaration of var loginAttemptsWindow; it will be inferred from the right-hand side pkg/metrics/graphitebridge/graphite.go:58:26: should omit type []string from declaration of var metricCategoryPrefix; it will be inferred from the right-hand side pkg/metrics/graphitebridge/graphite.go:69:22: should omit type []string from declaration of var trimMetricPrefix; it will be inferred from the right-hand side pkg/models/alert.go:37:36: should omit type error from declaration of var ErrCannotChangeStateOnPausedAlert; it will be inferred from the right-hand side pkg/models/alert.go:38:36: should omit type error from declaration of var ErrRequiresNewState; it will be inferred from the right-hand side pkg/models/datasource.go:61:28: should omit type map[string]bool from declaration of var knownDatasourcePlugins; it will be inferred from the right-hand side pkg/plugins/update_checker.go:16:13: should omit type http.Client from declaration of var httpClient; it will be inferred from the right-hand side pkg/services/alerting/engine.go:103:24: should omit type time.Duration from declaration of var unfinishedWorkTimeout; it will be inferred from the right-hand side pkg/services/alerting/engine.go:105:19: should omit type time.Duration from declaration of var alertTimeout; it will be inferred from the right-hand side pkg/services/alerting/engine.go:106:19: should omit type int from declaration of var alertMaxAttempts; it will be inferred from the right-hand side pkg/services/alerting/notifier.go:143:23: should omit type map[string]*NotifierPlugin from declaration of var notifierFactories; it will be inferred from the right-hand side pkg/services/alerting/rule.go:136:24: should omit type map[string]ConditionFactory from declaration of var conditionFactories; it will be inferred from the right-hand side pkg/services/alerting/conditions/evaluator.go:12:15: should omit type []string from declaration of var defaultTypes; it will be inferred from the right-hand side pkg/services/alerting/conditions/evaluator.go:13:15: should omit type []string from declaration of var rangedTypes; it will be inferred from the right-hand side pkg/services/alerting/notifiers/opsgenie.go:44:19: should omit type string from declaration of var opsgenieAlertURL; it will be inferred from the right-hand side pkg/services/alerting/notifiers/pagerduty.go:43:23: should omit type string from declaration of var pagerdutyEventApiUrl; it will be inferred from the right-hand side pkg/services/alerting/notifiers/telegram.go:21:17: should omit type string from declaration of var telegramApiUrl; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/config_reader_test.go:11:24: should omit type string from declaration of var simpleDashboardConfig; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/config_reader_test.go:12:24: should omit type string from declaration of var oldVersion; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/config_reader_test.go:13:24: should omit type string from declaration of var brokenConfigs; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/file_reader.go:22:30: should omit type time.Duration from declaration of var checkDiskForChangesInterval; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/file_reader.go:24:23: should omit type error from declaration of var ErrFolderNameMissing; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:15:34: should omit type string from declaration of var twoDatasourcesConfig; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:16:34: should omit type string from declaration of var twoDatasourcesConfigPurgeOthers; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:17:34: should omit type string from declaration of var doubleDatasourcesConfig; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:18:34: should omit type string from declaration of var allProperties; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:19:34: should omit type string from declaration of var versionZero; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:20:34: should omit type string from declaration of var brokenYaml; it will be inferred from the right-hand side pkg/services/sqlstore/stats.go:16:25: should omit type time.Duration from declaration of var activeUserTimeLimit; it will be inferred from the right-hand side pkg/services/sqlstore/migrator/mysql_dialect.go:69:14: should omit type bool from declaration of var hasLen1; it will be inferred from the right-hand side pkg/services/sqlstore/migrator/mysql_dialect.go:70:14: should omit type bool from declaration of var hasLen2; it will be inferred from the right-hand side pkg/services/sqlstore/migrator/postgres_dialect.go:95:14: should omit type bool from declaration of var hasLen1; it will be inferred from the right-hand side pkg/services/sqlstore/migrator/postgres_dialect.go:96:14: should omit type bool from declaration of var hasLen2; it will be inferred from the right-hand side pkg/setting/setting.go:42:15: should omit type string from declaration of var Env; it will be inferred from the right-hand side pkg/setting/setting.go:161:18: should omit type bool from declaration of var LdapAllowSignup; it will be inferred from the right-hand side pkg/setting/setting.go:473:30: should omit type bool from declaration of var skipStaticRootValidation; it will be inferred from the right-hand side pkg/tsdb/interval.go:14:21: should omit type time.Duration from declaration of var defaultMinInterval; it will be inferred from the right-hand side pkg/tsdb/interval.go:15:21: should omit type time.Duration from declaration of var year; it will be inferred from the right-hand side pkg/tsdb/interval.go:16:21: should omit type time.Duration from declaration of var day; it will be inferred from the right-hand side pkg/tsdb/cloudwatch/credentials.go:26:24: should omit type map[string]cache from declaration of var awsCredentialCache; it will be inferred from the right-hand side pkg/tsdb/influxdb/query.go:15:27: should omit type *regexp.Regexp from declaration of var regexpOperatorPattern; it will be inferred from the right-hand side pkg/tsdb/influxdb/query.go:16:27: should omit type *regexp.Regexp from declaration of var regexpMeasurementPattern; it will be inferred from the right-hand side pkg/tsdb/mssql/mssql_test.go:25:14: should omit type string from declaration of var serverIP; it will be inferred from the right-hand side
253 lines
7.3 KiB
Go
253 lines
7.3 KiB
Go
package datasources
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
|
"github.com/grafana/grafana/pkg/log"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
)
|
|
|
|
var (
|
|
logger log.Logger = log.New("fake.log")
|
|
|
|
twoDatasourcesConfig = "./test-configs/two-datasources"
|
|
twoDatasourcesConfigPurgeOthers = "./test-configs/insert-two-delete-two"
|
|
doubleDatasourcesConfig = "./test-configs/double-default"
|
|
allProperties = "./test-configs/all-properties"
|
|
versionZero = "./test-configs/version-0"
|
|
brokenYaml = "./test-configs/broken-yaml"
|
|
|
|
fakeRepo *fakeRepository
|
|
)
|
|
|
|
func TestDatasourceAsConfig(t *testing.T) {
|
|
Convey("Testing datasource as configuration", t, func() {
|
|
fakeRepo = &fakeRepository{}
|
|
bus.ClearBusHandlers()
|
|
bus.AddHandler("test", mockDelete)
|
|
bus.AddHandler("test", mockInsert)
|
|
bus.AddHandler("test", mockUpdate)
|
|
bus.AddHandler("test", mockGet)
|
|
bus.AddHandler("test", mockGetAll)
|
|
|
|
Convey("One configured datasource", func() {
|
|
Convey("no datasource in database", func() {
|
|
dc := newDatasourceProvisioner(logger)
|
|
err := dc.applyChanges(twoDatasourcesConfig)
|
|
if err != nil {
|
|
t.Fatalf("applyChanges return an error %v", err)
|
|
}
|
|
|
|
So(len(fakeRepo.deleted), ShouldEqual, 0)
|
|
So(len(fakeRepo.inserted), ShouldEqual, 2)
|
|
So(len(fakeRepo.updated), ShouldEqual, 0)
|
|
})
|
|
|
|
Convey("One datasource in database with same name", func() {
|
|
fakeRepo.loadAll = []*models.DataSource{
|
|
{Name: "Graphite", OrgId: 1, Id: 1},
|
|
}
|
|
|
|
Convey("should update one datasource", func() {
|
|
dc := newDatasourceProvisioner(logger)
|
|
err := dc.applyChanges(twoDatasourcesConfig)
|
|
if err != nil {
|
|
t.Fatalf("applyChanges return an error %v", err)
|
|
}
|
|
|
|
So(len(fakeRepo.deleted), ShouldEqual, 0)
|
|
So(len(fakeRepo.inserted), ShouldEqual, 1)
|
|
So(len(fakeRepo.updated), ShouldEqual, 1)
|
|
})
|
|
})
|
|
|
|
Convey("Two datasources with is_default", func() {
|
|
dc := newDatasourceProvisioner(logger)
|
|
err := dc.applyChanges(doubleDatasourcesConfig)
|
|
Convey("should raise error", func() {
|
|
So(err, ShouldEqual, ErrInvalidConfigToManyDefault)
|
|
})
|
|
})
|
|
})
|
|
|
|
Convey("Two configured datasource and purge others ", func() {
|
|
Convey("two other datasources in database", func() {
|
|
fakeRepo.loadAll = []*models.DataSource{
|
|
{Name: "old-graphite", OrgId: 1, Id: 1},
|
|
{Name: "old-graphite2", OrgId: 1, Id: 2},
|
|
}
|
|
|
|
Convey("should have two new datasources", func() {
|
|
dc := newDatasourceProvisioner(logger)
|
|
err := dc.applyChanges(twoDatasourcesConfigPurgeOthers)
|
|
if err != nil {
|
|
t.Fatalf("applyChanges return an error %v", err)
|
|
}
|
|
|
|
So(len(fakeRepo.deleted), ShouldEqual, 2)
|
|
So(len(fakeRepo.inserted), ShouldEqual, 2)
|
|
So(len(fakeRepo.updated), ShouldEqual, 0)
|
|
})
|
|
})
|
|
})
|
|
|
|
Convey("Two configured datasource and purge others = false", func() {
|
|
Convey("two other datasources in database", func() {
|
|
fakeRepo.loadAll = []*models.DataSource{
|
|
{Name: "Graphite", OrgId: 1, Id: 1},
|
|
{Name: "old-graphite2", OrgId: 1, Id: 2},
|
|
}
|
|
|
|
Convey("should have two new datasources", func() {
|
|
dc := newDatasourceProvisioner(logger)
|
|
err := dc.applyChanges(twoDatasourcesConfig)
|
|
if err != nil {
|
|
t.Fatalf("applyChanges return an error %v", err)
|
|
}
|
|
|
|
So(len(fakeRepo.deleted), ShouldEqual, 0)
|
|
So(len(fakeRepo.inserted), ShouldEqual, 1)
|
|
So(len(fakeRepo.updated), ShouldEqual, 1)
|
|
})
|
|
})
|
|
})
|
|
|
|
Convey("broken yaml should return error", func() {
|
|
reader := &configReader{}
|
|
_, err := reader.readConfig(brokenYaml)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("skip invalid directory", func() {
|
|
cfgProvifer := &configReader{log: log.New("test logger")}
|
|
cfg, err := cfgProvifer.readConfig("./invalid-directory")
|
|
if err != nil {
|
|
t.Fatalf("readConfig return an error %v", err)
|
|
}
|
|
|
|
So(len(cfg), ShouldEqual, 0)
|
|
})
|
|
|
|
Convey("can read all properties from version 1", func() {
|
|
cfgProvifer := &configReader{log: log.New("test logger")}
|
|
cfg, err := cfgProvifer.readConfig(allProperties)
|
|
if err != nil {
|
|
t.Fatalf("readConfig return an error %v", err)
|
|
}
|
|
|
|
So(len(cfg), ShouldEqual, 3)
|
|
|
|
dsCfg := cfg[0]
|
|
|
|
So(dsCfg.ApiVersion, ShouldEqual, 1)
|
|
|
|
validateDatasource(dsCfg)
|
|
validateDeleteDatasources(dsCfg)
|
|
|
|
dsCount := 0
|
|
delDsCount := 0
|
|
|
|
for _, c := range cfg {
|
|
dsCount += len(c.Datasources)
|
|
delDsCount += len(c.DeleteDatasources)
|
|
}
|
|
|
|
So(dsCount, ShouldEqual, 2)
|
|
So(delDsCount, ShouldEqual, 1)
|
|
})
|
|
|
|
Convey("can read all properties from version 0", func() {
|
|
cfgProvifer := &configReader{log: log.New("test logger")}
|
|
cfg, err := cfgProvifer.readConfig(versionZero)
|
|
if err != nil {
|
|
t.Fatalf("readConfig return an error %v", err)
|
|
}
|
|
|
|
So(len(cfg), ShouldEqual, 1)
|
|
|
|
dsCfg := cfg[0]
|
|
|
|
So(dsCfg.ApiVersion, ShouldEqual, 0)
|
|
|
|
validateDatasource(dsCfg)
|
|
validateDeleteDatasources(dsCfg)
|
|
})
|
|
})
|
|
}
|
|
func validateDeleteDatasources(dsCfg *DatasourcesAsConfig) {
|
|
So(len(dsCfg.DeleteDatasources), ShouldEqual, 1)
|
|
deleteDs := dsCfg.DeleteDatasources[0]
|
|
So(deleteDs.Name, ShouldEqual, "old-graphite3")
|
|
So(deleteDs.OrgId, ShouldEqual, 2)
|
|
}
|
|
func validateDatasource(dsCfg *DatasourcesAsConfig) {
|
|
ds := dsCfg.Datasources[0]
|
|
So(ds.Name, ShouldEqual, "name")
|
|
So(ds.Type, ShouldEqual, "type")
|
|
So(ds.Access, ShouldEqual, models.DS_ACCESS_PROXY)
|
|
So(ds.OrgId, ShouldEqual, 2)
|
|
So(ds.Url, ShouldEqual, "url")
|
|
So(ds.User, ShouldEqual, "user")
|
|
So(ds.Password, ShouldEqual, "password")
|
|
So(ds.Database, ShouldEqual, "database")
|
|
So(ds.BasicAuth, ShouldBeTrue)
|
|
So(ds.BasicAuthUser, ShouldEqual, "basic_auth_user")
|
|
So(ds.BasicAuthPassword, ShouldEqual, "basic_auth_password")
|
|
So(ds.WithCredentials, ShouldBeTrue)
|
|
So(ds.IsDefault, ShouldBeTrue)
|
|
So(ds.Editable, ShouldBeTrue)
|
|
So(ds.Version, ShouldEqual, 10)
|
|
|
|
So(len(ds.JsonData), ShouldBeGreaterThan, 2)
|
|
So(ds.JsonData["graphiteVersion"], ShouldEqual, "1.1")
|
|
So(ds.JsonData["tlsAuth"], ShouldEqual, true)
|
|
So(ds.JsonData["tlsAuthWithCACert"], ShouldEqual, true)
|
|
|
|
So(len(ds.SecureJsonData), ShouldBeGreaterThan, 2)
|
|
So(ds.SecureJsonData["tlsCACert"], ShouldEqual, "MjNOcW9RdkbUDHZmpco2HCYzVq9dE+i6Yi+gmUJotq5CDA==")
|
|
So(ds.SecureJsonData["tlsClientCert"], ShouldEqual, "ckN0dGlyMXN503YNfjTcf9CV+GGQneN+xmAclQ==")
|
|
So(ds.SecureJsonData["tlsClientKey"], ShouldEqual, "ZkN4aG1aNkja/gKAB1wlnKFIsy2SRDq4slrM0A==")
|
|
}
|
|
|
|
type fakeRepository struct {
|
|
inserted []*models.AddDataSourceCommand
|
|
deleted []*models.DeleteDataSourceByNameCommand
|
|
updated []*models.UpdateDataSourceCommand
|
|
|
|
loadAll []*models.DataSource
|
|
}
|
|
|
|
func mockDelete(cmd *models.DeleteDataSourceByNameCommand) error {
|
|
fakeRepo.deleted = append(fakeRepo.deleted, cmd)
|
|
return nil
|
|
}
|
|
|
|
func mockUpdate(cmd *models.UpdateDataSourceCommand) error {
|
|
fakeRepo.updated = append(fakeRepo.updated, cmd)
|
|
return nil
|
|
}
|
|
|
|
func mockInsert(cmd *models.AddDataSourceCommand) error {
|
|
fakeRepo.inserted = append(fakeRepo.inserted, cmd)
|
|
return nil
|
|
}
|
|
|
|
func mockGetAll(cmd *models.GetAllDataSourcesQuery) error {
|
|
cmd.Result = fakeRepo.loadAll
|
|
return nil
|
|
}
|
|
|
|
func mockGet(cmd *models.GetDataSourceByNameQuery) error {
|
|
for _, v := range fakeRepo.loadAll {
|
|
if cmd.Name == v.Name && cmd.OrgId == v.OrgId {
|
|
cmd.Result = v
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return models.ErrDataSourceNotFound
|
|
}
|