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:
Dan Cech
2024-02-09 09:35:39 -05:00
committed by GitHub
parent de4acb27ce
commit 790e1feb93
104 changed files with 801 additions and 189 deletions

View File

@ -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
}