Skip to content

Support more database types on unit tests #17545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,20 @@ steps:
GITHUB_READ_TOKEN:
from_secret: github_read_token

- name: unit-test-mysql
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
user: gitea
commands:
- make test-backend
environment:
GOPROXY: off
TAGS: bindata sqlite sqlite_unlock_notify
RACE_ENABLED: true
GITEA_UNIT_TESTS_DB_TYPE: mysql
GITEA_UNIT_TESTS_DB_CONNSTR: root:@tcp(mysql:3306)/gitea_test?charset=utf8mb4
GITHUB_READ_TOKEN:
from_secret: github_read_token

- name: unit-test-gogit
pull: always
image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env
Expand Down
2 changes: 1 addition & 1 deletion contrib/fixtures/fixture_generation.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var (
func main() {
pathToGiteaRoot := "."
fixturesDir = filepath.Join(pathToGiteaRoot, "models", "fixtures")
if err := unittest.CreateTestEngine(unittest.FixturesOptions{
if err := unittest.InitTestEngine(unittest.FixturesOptions{
Dir: fixturesDir,
}); err != nil {
fmt.Printf("CreateTestEngine: %+v", err)
Expand Down
90 changes: 86 additions & 4 deletions models/unittest/testdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
package unittest

import (
"database/sql"
"errors"
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
"testing"

"code.gitea.io/gitea/models/db"
Expand All @@ -19,7 +22,9 @@ import (

"github.com/stretchr/testify/assert"
"xorm.io/xorm"
"xorm.io/xorm/dialects"
"xorm.io/xorm/names"
"xorm.io/xorm/schemas"
)

// giteaRoot a path to the gitea root
Expand Down Expand Up @@ -57,7 +62,7 @@ func MainTest(m *testing.M, pathToGiteaRoot string, fixtureFiles ...string) {
}
}

if err = CreateTestEngine(opts); err != nil {
if err = InitTestEngine(opts); err != nil {
fatalTestError("Error creating test engine: %v\n", err)
}

Expand Down Expand Up @@ -111,15 +116,92 @@ func MainTest(m *testing.M, pathToGiteaRoot string, fixtureFiles ...string) {
os.Exit(exitStatus)
}

func createDB(driverName, connStr string) error {
driver := dialects.QueryDriver(driverName)
if driver == nil {
return fmt.Errorf("Unsupported driver name: %v", driver)
}
uri, err := driver.Parse(driverName, connStr)
if err != nil {
return err
}
dbType := uri.DBType
dbName := uri.DBName
dbSchema := uri.Schema

switch dbType {
case schemas.SQLITE: // ignore the creation
case schemas.MSSQL:
db, err := sql.Open(driverName, strings.ReplaceAll(connStr, dbName, "master"))
if err != nil {
return err
}
if _, err = db.Exec(fmt.Sprintf("If(db_id(N'%s') IS NULL) BEGIN CREATE DATABASE %s; END;", dbName, dbName)); err != nil {
return fmt.Errorf("db.Exec: %v", err)
}
db.Close()
case schemas.POSTGRES:
db, err := sql.Open(driverName, connStr)
if err != nil {
return err
}
rows, err := db.Query(fmt.Sprintf("SELECT 1 FROM pg_database WHERE datname = '%s'", dbName))
if err != nil {
return fmt.Errorf("db.Query: %v", err)
}
defer rows.Close()

if !rows.Next() {
if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", dbName)); err != nil {
return fmt.Errorf("CREATE DATABASE: %v", err)
}
}
if dbSchema != "" {
if _, err = db.Exec("CREATE SCHEMA IF NOT EXISTS " + dbSchema); err != nil {
return fmt.Errorf("CREATE SCHEMA: %v", err)
}
}
db.Close()
case schemas.MYSQL:
db, err := sql.Open(driverName, strings.ReplaceAll(connStr, dbName, "mysql"))
if err != nil {
return err
}
if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName)); err != nil {
return fmt.Errorf("db.Exec: %v", err)
}
db.Close()
default:
return errors.New("Unsupported database for unit test")
}
return nil
}

// FixturesOptions fixtures needs to be loaded options
type FixturesOptions struct {
Dir string
Files []string
}

// CreateTestEngine creates a memory database and loads the fixture data from fixturesDir
func CreateTestEngine(opts FixturesOptions) error {
x, err := xorm.NewEngine("sqlite3", "file::memory:?cache=shared&_txlock=immediate")
// InitTestEngine creates a memory database and loads the fixture data from fixturesDir
func InitTestEngine(opts FixturesOptions) error {
var dbType = "sqlite3"
var dbConnStr = "file::memory:?cache=shared&_txlock=immediate"

if os.Getenv("GITEA_UNIT_TESTS_DB_TYPE") != "" {
dbType = os.Getenv("GITEA_UNIT_TESTS_DB_TYPE")
}

if os.Getenv("GITEA_UNIT_TESTS_DB_CONNSTR") != "" {
dbConnStr = os.Getenv("GITEA_UNIT_TESTS_DB_CONNSTR")
}

if err := createDB(dbType, dbConnStr); err != nil {
return fmt.Errorf("createDB failed: %v", err)
}

var err error
x, err := xorm.NewEngine(dbType, dbConnStr)
if err != nil {
return err
}
Expand Down