aboutsummaryrefslogtreecommitdiff
path: root/internal/dbtest
diff options
context:
space:
mode:
authorJoe Chen <jc@unknwon.io>2022-06-12 14:15:01 +0800
committerGitHub <noreply@github.com>2022-06-12 14:15:01 +0800
commitb772603d78cb10f0501f3d08b01553bb33914b6e (patch)
tree5f160df17f1bbd357370b3aeeb5289b0a5c3c08d /internal/dbtest
parent2e19f5a3c8193776685a5e9fea9ca8663f14dd8d (diff)
migrations: add tests and remove XORM (#7050)
Diffstat (limited to 'internal/dbtest')
-rw-r--r--internal/dbtest/dbtest.go149
1 files changed, 149 insertions, 0 deletions
diff --git a/internal/dbtest/dbtest.go b/internal/dbtest/dbtest.go
new file mode 100644
index 00000000..1183d732
--- /dev/null
+++ b/internal/dbtest/dbtest.go
@@ -0,0 +1,149 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package dbtest
+
+import (
+ "database/sql"
+ "fmt"
+ "os"
+ "path/filepath"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+ "gorm.io/gorm"
+ "gorm.io/gorm/schema"
+
+ "gogs.io/gogs/internal/conf"
+ "gogs.io/gogs/internal/dbutil"
+)
+
+// NewDB creates a new test database and initializes the given list of tables
+// for the suite. The test database is dropped after testing is completed unless
+// failed.
+func NewDB(t *testing.T, suite string, tables ...interface{}) *gorm.DB {
+ dbType := os.Getenv("GOGS_DATABASE_TYPE")
+
+ var dbName string
+ var dbOpts conf.DatabaseOpts
+ var cleanup func(db *gorm.DB)
+ switch dbType {
+ case "mysql":
+ dbOpts = conf.DatabaseOpts{
+ Type: "mysql",
+ Host: os.ExpandEnv("$MYSQL_HOST:$MYSQL_PORT"),
+ Name: dbName,
+ User: os.Getenv("MYSQL_USER"),
+ Password: os.Getenv("MYSQL_PASSWORD"),
+ }
+
+ dsn, err := dbutil.NewDSN(dbOpts)
+ require.NoError(t, err)
+
+ sqlDB, err := sql.Open("mysql", dsn)
+ require.NoError(t, err)
+
+ // Set up test database
+ dbName = fmt.Sprintf("gogs-%s-%d", suite, time.Now().Unix())
+ _, err = sqlDB.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS `%s`", dbName))
+ require.NoError(t, err)
+
+ _, err = sqlDB.Exec(fmt.Sprintf("CREATE DATABASE `%s`", dbName))
+ require.NoError(t, err)
+
+ dbOpts.Name = dbName
+
+ cleanup = func(db *gorm.DB) {
+ db.Exec(fmt.Sprintf("DROP DATABASE `%s`", dbName))
+ _ = sqlDB.Close()
+ }
+ case "postgres":
+ dbOpts = conf.DatabaseOpts{
+ Type: "postgres",
+ Host: os.ExpandEnv("$PGHOST:$PGPORT"),
+ Name: dbName,
+ Schema: "public",
+ User: os.Getenv("PGUSER"),
+ Password: os.Getenv("PGPASSWORD"),
+ SSLMode: os.Getenv("PGSSLMODE"),
+ }
+
+ dsn, err := dbutil.NewDSN(dbOpts)
+ require.NoError(t, err)
+
+ sqlDB, err := sql.Open("pgx", dsn)
+ require.NoError(t, err)
+
+ // Set up test database
+ dbName = fmt.Sprintf("gogs-%s-%d", suite, time.Now().Unix())
+ _, err = sqlDB.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %q", dbName))
+ require.NoError(t, err)
+
+ _, err = sqlDB.Exec(fmt.Sprintf("CREATE DATABASE %q", dbName))
+ require.NoError(t, err)
+
+ dbOpts.Name = dbName
+
+ cleanup = func(db *gorm.DB) {
+ db.Exec(fmt.Sprintf(`DROP DATABASE %q`, dbName))
+ _ = sqlDB.Close()
+ }
+ case "sqlite":
+ dbName = filepath.Join(os.TempDir(), fmt.Sprintf("gogs-%s-%d.db", suite, time.Now().Unix()))
+ dbOpts = conf.DatabaseOpts{
+ Type: "sqlite",
+ Path: dbName,
+ }
+ cleanup = func(db *gorm.DB) {
+ sqlDB, err := db.DB()
+ if err == nil {
+ _ = sqlDB.Close()
+ }
+ _ = os.Remove(dbName)
+ }
+ default:
+ dbName = filepath.Join(os.TempDir(), fmt.Sprintf("gogs-%s-%d.db", suite, time.Now().Unix()))
+ dbOpts = conf.DatabaseOpts{
+ Type: "sqlite3",
+ Path: dbName,
+ }
+ cleanup = func(db *gorm.DB) {
+ sqlDB, err := db.DB()
+ if err == nil {
+ _ = sqlDB.Close()
+ }
+ _ = os.Remove(dbName)
+ }
+ }
+
+ now := time.Now().UTC().Truncate(time.Second)
+ db, err := dbutil.OpenDB(
+ dbOpts,
+ &gorm.Config{
+ SkipDefaultTransaction: true,
+ NamingStrategy: schema.NamingStrategy{
+ SingularTable: true,
+ },
+ NowFunc: func() time.Time {
+ return now
+ },
+ },
+ )
+ require.NoError(t, err)
+
+ t.Cleanup(func() {
+ if t.Failed() {
+ t.Logf("Database %q left intact for inspection", dbName)
+ return
+ }
+
+ cleanup(db)
+ })
+
+ err = db.Migrator().AutoMigrate(tables...)
+ require.NoError(t, err)
+
+ return db
+}