SQLStore: Run tests as integration tests (#28265)
* sqlstore: Run tests as integration tests * Truncate database instead of re-creating it on each test * Fix test description See https://github.com/grafana/grafana/pull/12129 * Fix lint issues * Fix postgres dialect after review suggestion * Rename and document functions after review suggestion * Add periods * Fix auto-increment value for mysql dialect Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
This commit is contained in:
co-authored by
Emil Tullstedt
parent
c07896063b
commit
4937f0daab
@@ -45,6 +45,7 @@ type Dialect interface {
|
||||
PostInsertId(table string, sess *xorm.Session) error
|
||||
|
||||
CleanDB() error
|
||||
TruncateDBTables() error
|
||||
NoOpSql() string
|
||||
|
||||
IsUniqueConstraintViolation(err error) bool
|
||||
@@ -270,3 +271,7 @@ func (db *BaseDialect) CleanDB() error {
|
||||
func (db *BaseDialect) NoOpSql() string {
|
||||
return "SELECT 0;"
|
||||
}
|
||||
|
||||
func (db *BaseDialect) TruncateDBTables() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -137,6 +138,36 @@ func (db *Mysql) CleanDB() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TruncateDBTables truncates all the tables.
|
||||
// A special case is the dashboard_acl table where we keep the default permissions.
|
||||
func (db *Mysql) TruncateDBTables() error {
|
||||
tables, err := db.engine.DBMetas()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sess := db.engine.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
for _, table := range tables {
|
||||
switch table.Name {
|
||||
case "dashboard_acl":
|
||||
// keep default dashboard permissions
|
||||
if _, err := sess.Exec(fmt.Sprintf("DELETE FROM %v WHERE dashboard_id != -1 AND org_id != -1;", db.Quote(table.Name))); err != nil {
|
||||
return errutil.Wrapf(err, "failed to truncate table %q", table.Name)
|
||||
}
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE %v AUTO_INCREMENT = 3;", db.Quote(table.Name))); err != nil {
|
||||
return errutil.Wrapf(err, "failed to reset table %q", table.Name)
|
||||
}
|
||||
default:
|
||||
if _, err := sess.Exec(fmt.Sprintf("TRUNCATE TABLE %v;", db.Quote(table.Name))); err != nil {
|
||||
return errutil.Wrapf(err, "failed to truncate table %q", table.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Mysql) isThisError(err error, errcode uint16) bool {
|
||||
if driverErr, ok := err.(*mysql.MySQLError); ok {
|
||||
if driverErr.Number == errcode {
|
||||
|
||||
@@ -140,6 +140,37 @@ func (db *Postgres) CleanDB() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TruncateDBTables truncates all the tables.
|
||||
// A special case is the dashboard_acl table where we keep the default permissions.
|
||||
func (db *Postgres) TruncateDBTables() error {
|
||||
sess := db.engine.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
for _, table := range db.engine.Tables {
|
||||
switch table.Name {
|
||||
case "":
|
||||
continue
|
||||
case "dashboard_acl":
|
||||
// keep default dashboard permissions
|
||||
if _, err := sess.Exec(fmt.Sprintf("DELETE FROM %v WHERE dashboard_id != -1 AND org_id != -1;", db.Quote(table.Name))); err != nil {
|
||||
return errutil.Wrapf(err, "failed to truncate table %q", table.Name)
|
||||
}
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER SEQUENCE %v RESTART WITH 3;", db.Quote(fmt.Sprintf("%v_id_seq", table.Name)))); err != nil {
|
||||
return errutil.Wrapf(err, "failed to reset table %q", table.Name)
|
||||
}
|
||||
default:
|
||||
if _, err := sess.Exec(fmt.Sprintf("TRUNCATE TABLE %v RESTART IDENTITY CASCADE;", db.Quote(table.Name))); err != nil {
|
||||
if db.isUndefinedTable(err) {
|
||||
continue
|
||||
}
|
||||
return errutil.Wrapf(err, "failed to truncate table %q", table.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Postgres) isThisError(err error, errcode string) bool {
|
||||
if driverErr, ok := err.(*pq.Error); ok {
|
||||
if string(driverErr.Code) == errcode {
|
||||
@@ -157,6 +188,10 @@ func (db *Postgres) ErrorMessage(err error) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (db *Postgres) isUndefinedTable(err error) bool {
|
||||
return db.isThisError(err, "42P01")
|
||||
}
|
||||
|
||||
func (db *Postgres) IsUniqueConstraintViolation(err error) bool {
|
||||
return db.isThisError(err, "23505")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package migrator
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
"github.com/mattn/go-sqlite3"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
@@ -85,6 +86,39 @@ func (db *Sqlite3) CleanDB() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TruncateDBTables deletes all data from all the tables and resets the sequences.
|
||||
// A special case is the dashboard_acl table where we keep the default permissions.
|
||||
func (db *Sqlite3) TruncateDBTables() error {
|
||||
tables, err := db.engine.DBMetas()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := db.engine.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
for _, table := range tables {
|
||||
switch table.Name {
|
||||
case "dashboard_acl":
|
||||
// keep default dashboard permissions
|
||||
if _, err := sess.Exec(fmt.Sprintf("DELETE FROM %q WHERE dashboard_id != -1 AND org_id != -1;", table.Name)); err != nil {
|
||||
return errutil.Wrapf(err, "failed to truncate table %q", table.Name)
|
||||
}
|
||||
if _, err := sess.Exec("UPDATE sqlite_sequence SET seq = 2 WHERE name = '%s';", table.Name); err != nil {
|
||||
return errutil.Wrapf(err, "failed to cleanup sqlite_sequence")
|
||||
}
|
||||
default:
|
||||
if _, err := sess.Exec(fmt.Sprintf("DELETE FROM %s;", table.Name)); err != nil {
|
||||
return errutil.Wrapf(err, "failed to truncate table %q", table.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := sess.Exec("UPDATE sqlite_sequence SET seq = 0 WHERE name != 'dashboard_acl';"); err != nil {
|
||||
return errutil.Wrapf(err, "failed to cleanup sqlite_sequence")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Sqlite3) isThisError(err error, errcode int) bool {
|
||||
if driverErr, ok := err.(sqlite3.Error); ok {
|
||||
if int(driverErr.ExtendedCode) == errcode {
|
||||
|
||||
Reference in New Issue
Block a user