Chore: Update test database initialization (#81673)
* streamline initialization of test databases, support on-disk sqlite test db * clean up test databases * introduce testsuite helper * use testsuite everywhere we use a test db * update documentation * improve error handling * disable entity integration test until we can figure out locking error
This commit is contained in:
@@ -2,7 +2,6 @@ package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -105,37 +104,6 @@ func convertToRawPermissions(permissions []accesscontrol.Permission) []rawPermis
|
||||
return raw
|
||||
}
|
||||
|
||||
func getDBType() string {
|
||||
dbType := migrator.SQLite
|
||||
|
||||
// environment variable present for test db?
|
||||
if db, present := os.LookupEnv("GRAFANA_TEST_DB"); present {
|
||||
dbType = db
|
||||
}
|
||||
return dbType
|
||||
}
|
||||
|
||||
func getTestDB(t *testing.T, dbType string) sqlutil.TestDB {
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return sqlutil.MySQLTestDB()
|
||||
case "postgres":
|
||||
return sqlutil.PostgresTestDB()
|
||||
default:
|
||||
f, err := os.CreateTemp(".", "grafana-test-db-")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
err := os.Remove(f.Name())
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
return sqlutil.TestDB{
|
||||
DriverName: "sqlite3",
|
||||
ConnStr: f.Name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrations(t *testing.T) {
|
||||
// Run initial migration to have a working DB
|
||||
x := setupTestDB(t)
|
||||
@@ -253,12 +221,21 @@ func TestMigrations(t *testing.T) {
|
||||
|
||||
func setupTestDB(t *testing.T) *xorm.Engine {
|
||||
t.Helper()
|
||||
dbType := getDBType()
|
||||
testDB := getTestDB(t, dbType)
|
||||
dbType := sqlutil.GetTestDBType()
|
||||
testDB, err := sqlutil.GetTestDB(dbType)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(testDB.Cleanup)
|
||||
|
||||
x, err := xorm.NewEngine(testDB.DriverName, testDB.ConnStr)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
if err := x.Close(); err != nil {
|
||||
fmt.Printf("failed to close xorm engine: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
err = migrator.NewDialect(x.DriverName()).CleanDB(x)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package migrations
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -21,13 +20,23 @@ import (
|
||||
)
|
||||
|
||||
func TestMigrations(t *testing.T) {
|
||||
testDB := sqlutil.SQLite3TestDB()
|
||||
testDB, err := sqlutil.GetTestDB(SQLite)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(testDB.Cleanup)
|
||||
|
||||
const query = `select count(*) as count from migration_log`
|
||||
result := struct{ Count int }{}
|
||||
|
||||
x, err := xorm.NewEngine(testDB.DriverName, testDB.ConnStr)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
if err := x.Close(); err != nil {
|
||||
fmt.Printf("failed to close xorm engine: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
err = NewDialect(x.DriverName()).CleanDB(x)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -61,16 +70,25 @@ func TestMigrations(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMigrationLock(t *testing.T) {
|
||||
dbType := getDBType()
|
||||
dbType := sqlutil.GetTestDBType()
|
||||
if dbType == SQLite {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
testDB := getTestDB(t, dbType)
|
||||
testDB, err := sqlutil.GetTestDB(dbType)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(testDB.Cleanup)
|
||||
|
||||
x, err := xorm.NewEngine(testDB.DriverName, testDB.ConnStr)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
if err := x.Close(); err != nil {
|
||||
fmt.Printf("failed to close xorm engine: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
dialect := NewDialect(x.DriverName())
|
||||
|
||||
sess := x.NewSession()
|
||||
@@ -157,17 +175,28 @@ func TestMigrationLock(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMigratorLocking(t *testing.T) {
|
||||
dbType := getDBType()
|
||||
testDB := getTestDB(t, dbType)
|
||||
dbType := sqlutil.GetTestDBType()
|
||||
|
||||
// skip for SQLite for now since it occasionally fails for not clear reason
|
||||
// anyway starting migrations concurretly for the same migrator is impossible use case
|
||||
if dbType == SQLite {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
testDB, err := sqlutil.GetTestDB(dbType)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(testDB.Cleanup)
|
||||
|
||||
x, err := xorm.NewEngine(testDB.DriverName, testDB.ConnStr)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
if err := x.Close(); err != nil {
|
||||
fmt.Printf("failed to close xorm engine: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
err = NewDialect(x.DriverName()).CleanDB(x)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -194,17 +223,27 @@ func TestMigratorLocking(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDatabaseLocking(t *testing.T) {
|
||||
dbType := getDBType()
|
||||
dbType := sqlutil.GetTestDBType()
|
||||
|
||||
// skip for SQLite since there is no database locking (only migrator locking)
|
||||
if dbType == SQLite {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
testDB := getTestDB(t, dbType)
|
||||
testDB, err := sqlutil.GetTestDB(dbType)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(testDB.Cleanup)
|
||||
|
||||
x, err := xorm.NewEngine(testDB.DriverName, testDB.ConnStr)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
if err := x.Close(); err != nil {
|
||||
fmt.Printf("failed to close xorm engine: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
err = NewDialect(x.DriverName()).CleanDB(x)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -280,37 +319,6 @@ func checkStepsAndDatabaseMatch(t *testing.T, mg *Migrator, expected []string) {
|
||||
require.Failf(t, "the number of migrations does not match log in database", msg)
|
||||
}
|
||||
|
||||
func getDBType() string {
|
||||
dbType := SQLite
|
||||
|
||||
// environment variable present for test db?
|
||||
if db, present := os.LookupEnv("GRAFANA_TEST_DB"); present {
|
||||
dbType = db
|
||||
}
|
||||
return dbType
|
||||
}
|
||||
|
||||
func getTestDB(t *testing.T, dbType string) sqlutil.TestDB {
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return sqlutil.MySQLTestDB()
|
||||
case "postgres":
|
||||
return sqlutil.PostgresTestDB()
|
||||
default:
|
||||
f, err := os.CreateTemp(".", "grafana-test-db-")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
err := os.Remove(f.Name())
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
return sqlutil.TestDB{
|
||||
DriverName: "sqlite3",
|
||||
ConnStr: f.Name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func replaceDBName(t *testing.T, connStr, dbType string) string {
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
|
||||
@@ -31,8 +31,13 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
|
||||
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/tests/testsuite"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
testsuite.Run(m)
|
||||
}
|
||||
|
||||
func TestIntegration_DashboardPermissionFilter(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/permissions"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/tests/testsuite"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
@@ -26,6 +27,10 @@ const (
|
||||
page int64 = 1
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
testsuite.Run(m)
|
||||
}
|
||||
|
||||
func TestBuilder_EqualResults_Basic(t *testing.T) {
|
||||
user := &user.SignedInUser{
|
||||
UserID: 1,
|
||||
|
||||
@@ -91,8 +91,8 @@ func ProvideService(cfg *setting.Cfg,
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func ProvideServiceForTests(cfg *setting.Cfg, features featuremgmt.FeatureToggles, migrations registry.DatabaseMigrator) (*SQLStore, error) {
|
||||
return initTestDB(cfg, features, migrations, InitTestDBOpt{EnsureDefaultOrgAndUser: true})
|
||||
func ProvideServiceForTests(t sqlutil.ITestDB, cfg *setting.Cfg, features featuremgmt.FeatureToggles, migrations registry.DatabaseMigrator) (*SQLStore, error) {
|
||||
return initTestDB(t, cfg, features, migrations, InitTestDBOpt{EnsureDefaultOrgAndUser: true})
|
||||
}
|
||||
|
||||
func newSQLStore(cfg *setting.Cfg, engine *xorm.Engine,
|
||||
@@ -145,11 +145,6 @@ func (ss *SQLStore) Migrate(isDatabaseLockingEnabled bool) error {
|
||||
return migrator.Start(isDatabaseLockingEnabled, ss.dbCfg.MigrationLockAttemptTimeout)
|
||||
}
|
||||
|
||||
// Sync syncs changes to the database.
|
||||
func (ss *SQLStore) Sync() error {
|
||||
return ss.engine.Sync2()
|
||||
}
|
||||
|
||||
// Reset resets database state.
|
||||
// If default org and user creation is enabled, it will be ensured they exist in the database.
|
||||
func (ss *SQLStore) Reset() error {
|
||||
@@ -388,16 +383,10 @@ func (ss *SQLStore) RecursiveQueriesAreSupported() (bool, error) {
|
||||
return *ss.recursiveQueriesAreSupported, nil
|
||||
}
|
||||
|
||||
// ITestDB is an interface of arguments for testing db
|
||||
type ITestDB interface {
|
||||
Helper()
|
||||
Fatalf(format string, args ...any)
|
||||
Logf(format string, args ...any)
|
||||
Log(args ...any)
|
||||
}
|
||||
|
||||
var testSQLStoreSetup = false
|
||||
var testSQLStore *SQLStore
|
||||
var testSQLStoreMutex sync.Mutex
|
||||
var testSQLStoreCleanup []func()
|
||||
|
||||
// InitTestDBOpt contains options for InitTestDB.
|
||||
type InitTestDBOpt struct {
|
||||
@@ -407,10 +396,10 @@ type InitTestDBOpt struct {
|
||||
}
|
||||
|
||||
// InitTestDBWithMigration initializes the test DB given custom migrations.
|
||||
func InitTestDBWithMigration(t ITestDB, migration registry.DatabaseMigrator, opts ...InitTestDBOpt) *SQLStore {
|
||||
func InitTestDBWithMigration(t sqlutil.ITestDB, migration registry.DatabaseMigrator, opts ...InitTestDBOpt) *SQLStore {
|
||||
t.Helper()
|
||||
features := getFeaturesForTesting(opts...)
|
||||
store, err := initTestDB(setting.NewCfg(), features, migration, opts...)
|
||||
store, err := initTestDB(t, setting.NewCfg(), features, migration, opts...)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to initialize sql store: %s", err)
|
||||
}
|
||||
@@ -418,20 +407,46 @@ func InitTestDBWithMigration(t ITestDB, migration registry.DatabaseMigrator, opt
|
||||
}
|
||||
|
||||
// InitTestDB initializes the test DB.
|
||||
func InitTestDB(t ITestDB, opts ...InitTestDBOpt) *SQLStore {
|
||||
func InitTestDB(t sqlutil.ITestDB, opts ...InitTestDBOpt) *SQLStore {
|
||||
t.Helper()
|
||||
features := getFeaturesForTesting(opts...)
|
||||
|
||||
store, err := initTestDB(setting.NewCfg(), features, migrations.ProvideOSSMigrations(features), opts...)
|
||||
store, err := initTestDB(t, setting.NewCfg(), features, migrations.ProvideOSSMigrations(features), opts...)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to initialize sql store: %s", err)
|
||||
}
|
||||
return store
|
||||
}
|
||||
|
||||
func InitTestDBWithCfg(t ITestDB, opts ...InitTestDBOpt) (*SQLStore, *setting.Cfg) {
|
||||
store := InitTestDB(t, opts...)
|
||||
return store, store.Cfg
|
||||
func SetupTestDB() {
|
||||
testSQLStoreMutex.Lock()
|
||||
defer testSQLStoreMutex.Unlock()
|
||||
if testSQLStoreSetup {
|
||||
fmt.Printf("ERROR: Test DB already set up, SetupTestDB called twice\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
testSQLStoreSetup = true
|
||||
}
|
||||
|
||||
func CleanupTestDB() {
|
||||
testSQLStoreMutex.Lock()
|
||||
defer testSQLStoreMutex.Unlock()
|
||||
if !testSQLStoreSetup {
|
||||
fmt.Printf("ERROR: Test DB not set up, SetupTestDB not called\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
if testSQLStore != nil {
|
||||
if err := testSQLStore.GetEngine().Close(); err != nil {
|
||||
fmt.Printf("Failed to close testSQLStore engine: %s\n", err)
|
||||
}
|
||||
|
||||
for _, cleanup := range testSQLStoreCleanup {
|
||||
cleanup()
|
||||
}
|
||||
|
||||
testSQLStoreCleanup = []func(){}
|
||||
testSQLStore = nil
|
||||
}
|
||||
}
|
||||
|
||||
func getFeaturesForTesting(opts ...InitTestDBOpt) featuremgmt.FeatureToggles {
|
||||
@@ -450,24 +465,43 @@ func getFeaturesForTesting(opts ...InitTestDBOpt) featuremgmt.FeatureToggles {
|
||||
}
|
||||
|
||||
//nolint:gocyclo
|
||||
func initTestDB(testCfg *setting.Cfg,
|
||||
func initTestDB(t sqlutil.ITestDB, testCfg *setting.Cfg,
|
||||
features featuremgmt.FeatureToggles,
|
||||
migration registry.DatabaseMigrator,
|
||||
opts ...InitTestDBOpt) (*SQLStore, error) {
|
||||
testSQLStoreMutex.Lock()
|
||||
defer testSQLStoreMutex.Unlock()
|
||||
if !testSQLStoreSetup {
|
||||
t.Fatalf(`
|
||||
|
||||
ERROR: Test DB not set up, are you missing TestMain?
|
||||
|
||||
https://github.com/grafana/grafana/blob/main/contribute/backend/style-guide.md
|
||||
|
||||
Example:
|
||||
|
||||
package mypkg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/tests/testsuite"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
testsuite.Run(m)
|
||||
}
|
||||
|
||||
`)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(opts) == 0 {
|
||||
opts = []InitTestDBOpt{{EnsureDefaultOrgAndUser: false, FeatureFlags: []string{}}}
|
||||
}
|
||||
|
||||
if testSQLStore == nil {
|
||||
dbType := migrator.SQLite
|
||||
|
||||
// environment variable present for test db?
|
||||
if db, present := os.LookupEnv("GRAFANA_TEST_DB"); present {
|
||||
dbType = db
|
||||
}
|
||||
dbType := sqlutil.GetTestDBType()
|
||||
|
||||
// set test db config
|
||||
cfg := setting.NewCfg()
|
||||
@@ -482,21 +516,21 @@ func initTestDB(testCfg *setting.Cfg,
|
||||
if _, err := sec.NewKey("type", dbType); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
if _, err := sec.NewKey("connection_string", sqlutil.MySQLTestDB().ConnStr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "postgres":
|
||||
if _, err := sec.NewKey("connection_string", sqlutil.PostgresTestDB().ConnStr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
if _, err := sec.NewKey("connection_string", sqlutil.SQLite3TestDB().ConnStr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
testDB, err := sqlutil.GetTestDB(dbType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := sec.NewKey("connection_string", testDB.ConnStr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := sec.NewKey("path", testDB.Path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
testSQLStoreCleanup = append(testSQLStoreCleanup, testDB.Cleanup)
|
||||
|
||||
// useful if you already have a database that you want to use for tests.
|
||||
// cannot just set it on testSQLStore as it overrides the config in Init
|
||||
if _, present := os.LookupEnv("SKIP_MIGRATIONS"); present {
|
||||
@@ -539,24 +573,6 @@ func initTestDB(testCfg *setting.Cfg,
|
||||
if err := testSQLStore.Migrate(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := testSQLStore.Dialect.TruncateDBTables(engine); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := testSQLStore.Reset(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Make sure the changes are synced, so they get shared with eventual other DB connections
|
||||
// XXX: Why is this only relevant when not skipping migrations?
|
||||
if !testSQLStore.dbCfg.SkipMigrations {
|
||||
if err := testSQLStore.Sync(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return testSQLStore, nil
|
||||
}
|
||||
|
||||
// nolint:staticcheck
|
||||
|
||||
@@ -2,6 +2,7 @@ package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -11,6 +12,13 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
SetupTestDB()
|
||||
code := m.Run()
|
||||
CleanupTestDB()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func TestIntegrationIsUniqueConstraintViolation(t *testing.T) {
|
||||
store := InitTestDB(t)
|
||||
|
||||
|
||||
@@ -1,25 +1,123 @@
|
||||
package sqlutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// ITestDB is an interface of arguments for testing db
|
||||
type ITestDB interface {
|
||||
Helper()
|
||||
Fatalf(format string, args ...any)
|
||||
Logf(format string, args ...any)
|
||||
Log(args ...any)
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
type TestDB struct {
|
||||
DriverName string
|
||||
ConnStr string
|
||||
Path string
|
||||
Cleanup func()
|
||||
}
|
||||
|
||||
func SQLite3TestDB() TestDB {
|
||||
// To run all tests in a local test database, set ConnStr to "grafana_test.db"
|
||||
return TestDB{
|
||||
DriverName: "sqlite3",
|
||||
// ConnStr specifies an In-memory database shared between connections.
|
||||
ConnStr: "file::memory:?cache=shared",
|
||||
func GetTestDBType() string {
|
||||
dbType := "sqlite3"
|
||||
|
||||
// environment variable present for test db?
|
||||
if db, present := os.LookupEnv("GRAFANA_TEST_DB"); present {
|
||||
dbType = db
|
||||
}
|
||||
return dbType
|
||||
}
|
||||
|
||||
func MySQLTestDB() TestDB {
|
||||
func GetTestDB(dbType string) (*TestDB, error) {
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return mySQLTestDB()
|
||||
case "postgres":
|
||||
return postgresTestDB()
|
||||
case "sqlite3":
|
||||
return sqLite3TestDB()
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown test db type: %s", dbType)
|
||||
}
|
||||
|
||||
func sqLite3TestDB() (*TestDB, error) {
|
||||
if os.Getenv("SQLITE_INMEMORY") == "true" {
|
||||
return &TestDB{
|
||||
DriverName: "sqlite3",
|
||||
ConnStr: "file::memory:",
|
||||
Cleanup: func() {},
|
||||
}, nil
|
||||
}
|
||||
|
||||
ret := &TestDB{
|
||||
DriverName: "sqlite3",
|
||||
Cleanup: func() {},
|
||||
}
|
||||
|
||||
sqliteDb := os.Getenv("SQLITE_TEST_DB")
|
||||
if sqliteDb == "" {
|
||||
// try to create a database file in the user's cache directory
|
||||
dir, err := os.UserCacheDir()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if cache dir doesn't exist, fall back to temp dir
|
||||
if _, err := os.Stat(dir); errors.Is(err, fs.ErrNotExist) {
|
||||
dir = os.TempDir()
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = os.Mkdir(filepath.Join(dir, "grafana-test"), 0750)
|
||||
if err != nil && !errors.Is(err, fs.ErrExist) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f, err := os.CreateTemp(filepath.Join(dir, "grafana-test"), "grafana-test-*.db")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqliteDb = f.Name()
|
||||
|
||||
ret.Cleanup = func() {
|
||||
// remove db file if it exists
|
||||
err := os.Remove(sqliteDb)
|
||||
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
fmt.Printf("Error removing sqlite db file %s: %v\n", sqliteDb, err)
|
||||
}
|
||||
|
||||
// remove wal & shm files if they exist
|
||||
err = os.Remove(sqliteDb + "-wal")
|
||||
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
fmt.Printf("Error removing sqlite wal file %s: %v\n", sqliteDb+"-wal", err)
|
||||
}
|
||||
err = os.Remove(sqliteDb + "-shm")
|
||||
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
fmt.Printf("Error removing sqlite shm file %s: %v\n", sqliteDb+"-shm", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret.ConnStr = "file:" + sqliteDb + "?cache=private&mode=rwc"
|
||||
if os.Getenv("SQLITE_JOURNAL_MODE") != "false" {
|
||||
ret.ConnStr += "&_journal_mode=WAL"
|
||||
}
|
||||
ret.Path = sqliteDb
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func mySQLTestDB() (*TestDB, error) {
|
||||
host := os.Getenv("MYSQL_HOST")
|
||||
if host == "" {
|
||||
host = "localhost"
|
||||
@@ -29,13 +127,14 @@ func MySQLTestDB() TestDB {
|
||||
port = "3306"
|
||||
}
|
||||
conn_str := fmt.Sprintf("grafana:password@tcp(%s:%s)/grafana_tests?collation=utf8mb4_unicode_ci&sql_mode='ANSI_QUOTES'&parseTime=true", host, port)
|
||||
return TestDB{
|
||||
return &TestDB{
|
||||
DriverName: "mysql",
|
||||
ConnStr: conn_str,
|
||||
}
|
||||
Cleanup: func() {},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func PostgresTestDB() TestDB {
|
||||
func postgresTestDB() (*TestDB, error) {
|
||||
host := os.Getenv("POSTGRES_HOST")
|
||||
if host == "" {
|
||||
host = "localhost"
|
||||
@@ -44,25 +143,10 @@ func PostgresTestDB() TestDB {
|
||||
if port == "" {
|
||||
port = "5432"
|
||||
}
|
||||
connStr := fmt.Sprintf("user=grafanatest password=grafanatest host=%s port=%s dbname=grafanatest sslmode=disable",
|
||||
host, port)
|
||||
return TestDB{
|
||||
connStr := fmt.Sprintf("user=grafanatest password=grafanatest host=%s port=%s dbname=grafanatest sslmode=disable", host, port)
|
||||
return &TestDB{
|
||||
DriverName: "postgres",
|
||||
ConnStr: connStr,
|
||||
}
|
||||
}
|
||||
|
||||
func MSSQLTestDB() TestDB {
|
||||
host := os.Getenv("MSSQL_HOST")
|
||||
if host == "" {
|
||||
host = "localhost"
|
||||
}
|
||||
port := os.Getenv("MSSQL_PORT")
|
||||
if port == "" {
|
||||
port = "1433"
|
||||
}
|
||||
return TestDB{
|
||||
DriverName: "mssql",
|
||||
ConnStr: fmt.Sprintf("server=%s;port=%s;database=grafanatest;user id=grafana;password=Password!", host, port),
|
||||
}
|
||||
Cleanup: func() {},
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user