The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/sqlstore/database_config_test.go

223 lines
7.2 KiB

package sqlstore
import (
"errors"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/setting"
)
type databaseConfigTest struct {
name string
dbType string
dbHost string
dbURL string
dbUser string
dbPwd string
expConnStr string
features featuremgmt.FeatureToggles
err error
}
var databaseConfigTestCases = []databaseConfigTest{
{
name: "MySQL IPv4",
dbType: "mysql",
dbHost: "1.2.3.4:5678",
expConnStr: ":@tcp(1.2.3.4:5678)/test_db?collation=utf8mb4_unicode_ci&allowNativePasswords=true&clientFoundRows=true",
},
{
name: "Postgres IPv4",
dbType: "postgres",
dbHost: "1.2.3.4:5678",
expConnStr: "user='' host=1.2.3.4 port=5678 dbname=test_db sslmode='' sslcert='' sslkey='' sslrootcert=''",
},
{
name: "Postgres IPv4 (Default Port)",
dbType: "postgres",
dbHost: "1.2.3.4",
expConnStr: "user='' host=1.2.3.4 port=5432 dbname=test_db sslmode='' sslcert='' sslkey='' sslrootcert=''",
},
{
name: "Postgres username and password",
dbType: "postgres",
dbHost: "1.2.3.4",
dbUser: "grafana",
dbPwd: "password",
expConnStr: "user=grafana host=1.2.3.4 port=5432 dbname=test_db sslmode='' sslcert='' sslkey='' sslrootcert='' password=password",
},
{
name: "Postgres username no password",
dbType: "postgres",
dbHost: "1.2.3.4",
dbUser: "grafana",
dbPwd: "",
expConnStr: "user=grafana host=1.2.3.4 port=5432 dbname=test_db sslmode='' sslcert='' sslkey='' sslrootcert=''",
},
{
name: "MySQL IPv4 (Default Port)",
dbType: "mysql",
dbHost: "1.2.3.4",
expConnStr: ":@tcp(1.2.3.4)/test_db?collation=utf8mb4_unicode_ci&allowNativePasswords=true&clientFoundRows=true",
},
{
name: "MySQL IPv6",
dbType: "mysql",
dbHost: "[fe80::24e8:31b2:91df:b177]:1234",
expConnStr: ":@tcp([fe80::24e8:31b2:91df:b177]:1234)/test_db?collation=utf8mb4_unicode_ci&allowNativePasswords=true&clientFoundRows=true",
},
{
name: "Postgres IPv6",
dbType: "postgres",
dbHost: "[fe80::24e8:31b2:91df:b177]:1234",
expConnStr: "user='' host=fe80::24e8:31b2:91df:b177 port=1234 dbname=test_db sslmode='' sslcert='' sslkey='' sslrootcert=''",
},
{
name: "MySQL IPv6 (Default Port)",
dbType: "mysql",
dbHost: "[::1]",
expConnStr: ":@tcp([::1])/test_db?collation=utf8mb4_unicode_ci&allowNativePasswords=true&clientFoundRows=true",
},
{
name: "Postgres IPv6 (Default Port)",
dbType: "postgres",
dbHost: "[::1]",
expConnStr: "user='' host=::1 port=5432 dbname=test_db sslmode='' sslcert='' sslkey='' sslrootcert=''",
},
{
name: "Invalid database URL",
dbURL: "://invalid.com/",
err: &url.Error{Op: "parse", URL: "://invalid.com/", Err: errors.New("missing protocol scheme")},
},
{
name: "MySQL with ANSI_QUOTES mode",
dbType: "mysql",
dbHost: "[::1]",
features: featuremgmt.WithFeatures(featuremgmt.FlagMysqlAnsiQuotes),
expConnStr: ":@tcp([::1])/test_db?collation=utf8mb4_unicode_ci&allowNativePasswords=true&clientFoundRows=true&sql_mode='ANSI_QUOTES'",
},
}
func TestIntegrationSQLConnectionString(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
for _, testCase := range databaseConfigTestCases {
t.Run(testCase.name, func(t *testing.T) {
cfg := makeDatabaseTestConfig(t, testCase)
dbCfg, err := NewDatabaseConfig(cfg, testCase.features)
require.Equal(t, testCase.err, err)
if testCase.expConnStr != "" {
assert.Equal(t, testCase.expConnStr, dbCfg.ConnectionString)
}
})
}
}
func makeDatabaseTestConfig(t *testing.T, tc databaseConfigTest) *setting.Cfg {
t.Helper()
if tc.features == nil {
tc.features = featuremgmt.WithFeatures()
}
// nolint:staticcheck
cfg := setting.NewCfgWithFeatures(tc.features.IsEnabledGlobally)
sec, err := cfg.Raw.NewSection("database")
require.NoError(t, err)
_, err = sec.NewKey("type", tc.dbType)
require.NoError(t, err)
_, err = sec.NewKey("host", tc.dbHost)
require.NoError(t, err)
_, err = sec.NewKey("url", tc.dbURL)
require.NoError(t, err)
_, err = sec.NewKey("user", tc.dbUser)
require.NoError(t, err)
_, err = sec.NewKey("name", "test_db")
require.NoError(t, err)
_, err = sec.NewKey("password", tc.dbPwd)
require.NoError(t, err)
return cfg
}
func TestBuildConnectionStringPostgres(t *testing.T) {
testCases := []struct {
name string
dbCfg *DatabaseConfig
expectedConnStr string
}{
{
name: "Postgres with sslmode disable",
dbCfg: &DatabaseConfig{
Type: migrator.Postgres,
User: "grafana",
Pwd: "password",
Host: "127.0.0.1:5432",
Name: "grafana_test",
SslMode: "disable",
},
expectedConnStr: "user=grafana host=127.0.0.1 port=5432 dbname=grafana_test sslmode=disable sslcert='' sslkey='' sslrootcert='' password=password",
},
{
name: "Postgres with sslmode verify-ca",
dbCfg: &DatabaseConfig{
Type: migrator.Postgres,
User: "grafana",
Pwd: "password",
Host: "127.0.0.1:5432",
Name: "grafana_test",
SslMode: "verify-ca",
CaCertPath: "/path/to/ca_cert",
ClientKeyPath: "/path/to/client_key",
ClientCertPath: "/path/to/client_cert",
},
expectedConnStr: "user=grafana host=127.0.0.1 port=5432 dbname=grafana_test sslmode=verify-ca sslcert=/path/to/client_cert sslkey=/path/to/client_key sslrootcert=/path/to/ca_cert password=password",
},
{
name: "Postgres with sslmode verify-ca without SNI",
dbCfg: &DatabaseConfig{
Type: migrator.Postgres,
User: "grafana",
Pwd: "password",
Host: "127.0.0.1:5432",
Name: "grafana_test",
SslMode: "verify-ca",
CaCertPath: "/path/to/ca_cert",
ClientKeyPath: "/path/to/client_key",
ClientCertPath: "/path/to/client_cert",
SSLSNI: "0",
},
expectedConnStr: "user=grafana host=127.0.0.1 port=5432 dbname=grafana_test sslmode=verify-ca sslcert=/path/to/client_cert sslkey=/path/to/client_key sslrootcert=/path/to/ca_cert sslsni=0 password=password",
},
{
name: "Postgres with sslmode verify-ca with SNI",
dbCfg: &DatabaseConfig{
Type: migrator.Postgres,
User: "grafana",
Pwd: "password",
Host: "127.0.0.1:5432",
Name: "grafana_test",
SslMode: "verify-ca",
CaCertPath: "/path/to/ca_cert",
ClientKeyPath: "/path/to/client_key",
ClientCertPath: "/path/to/client_cert",
SSLSNI: "1",
},
expectedConnStr: "user=grafana host=127.0.0.1 port=5432 dbname=grafana_test sslmode=verify-ca sslcert=/path/to/client_cert sslkey=/path/to/client_key sslrootcert=/path/to/ca_cert sslsni=1 password=password",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.dbCfg.buildConnectionString(&setting.Cfg{}, nil)
assert.NoError(t, err)
assert.Equal(t, tc.expectedConnStr, tc.dbCfg.ConnectionString)
})
}
}