mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Run unit tests in separate databases to avoid conflicts
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
@@ -24,7 +24,7 @@ services:
|
||||
PHOTOPRISM_TIDB_PASSWORD: "photoprism"
|
||||
PHOTOPRISM_DATABASE_DRIVER: "tidb"
|
||||
PHOTOPRISM_DATABASE_DSN: "root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TEST_DSN: "photoprism:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TEST_DSN: "root:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SUBTITLE: "Browse your life"
|
||||
PHOTOPRISM_DESCRIPTION: "Personal Photo Management tested by Travis CI."
|
||||
@@ -47,6 +47,8 @@ services:
|
||||
command: mysqld --port=4001 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=1024
|
||||
expose:
|
||||
- "4001"
|
||||
volumes:
|
||||
- "./scripts/test-db.sql:/docker-entrypoint-initdb.d/test-db.sql"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: photoprism
|
||||
MYSQL_USER: photoprism
|
||||
|
||||
@@ -28,7 +28,7 @@ services:
|
||||
PHOTOPRISM_TIDB_PASSWORD: "photoprism"
|
||||
PHOTOPRISM_DATABASE_DRIVER: "tidb"
|
||||
PHOTOPRISM_DATABASE_DSN: "root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TEST_DSN: "photoprism:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TEST_DSN: "root:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_ASSETS_PATH: "/go/src/github.com/photoprism/photoprism/assets"
|
||||
PHOTOPRISM_CACHE_PATH: "/go/src/github.com/photoprism/photoprism/assets/cache"
|
||||
PHOTOPRISM_RESOURCES_PATH: "/go/src/github.com/photoprism/photoprism/assets/resources"
|
||||
@@ -48,6 +48,8 @@ services:
|
||||
- "4001"
|
||||
ports:
|
||||
- "4001:4001" # MySQL (for tests)
|
||||
volumes:
|
||||
- "./scripts/test-db.sql:/docker-entrypoint-initdb.d/test-db.sql"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: photoprism
|
||||
MYSQL_USER: photoprism
|
||||
|
||||
@@ -61,10 +61,10 @@ func (c *Config) InitDb() {
|
||||
entity.MigrateDb()
|
||||
}
|
||||
|
||||
// ResetDb drops all tables in the currently configured database and re-creates them.
|
||||
func (c *Config) ResetDb() {
|
||||
// InitTestDb drops all tables in the currently configured database and re-creates them.
|
||||
func (c *Config) InitTestDb() {
|
||||
entity.SetDbProvider(c)
|
||||
entity.InitTestFixtures()
|
||||
entity.ResetTestFixtures()
|
||||
}
|
||||
|
||||
// connectToDatabase establishes a database connection.
|
||||
|
||||
@@ -102,7 +102,7 @@ func NewTestConfig() *Config {
|
||||
log.Fatalf("config: %s", err.Error())
|
||||
}
|
||||
|
||||
c.ResetDb()
|
||||
c.InitTestDb()
|
||||
|
||||
thumb.Size = c.ThumbSize()
|
||||
thumb.Limit = c.ThumbLimit()
|
||||
|
||||
@@ -15,12 +15,13 @@ func TestCreateAccount(t *testing.T) {
|
||||
accountForm, err := form.NewAccount(account)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
model, err := CreateAccount(accountForm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "/home", model.SharePath)
|
||||
@@ -56,12 +57,12 @@ func TestAccount_Save(t *testing.T) {
|
||||
accountForm, err := form.NewAccount(account)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
model, err := CreateAccount(accountForm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "Foo", model.AccName)
|
||||
@@ -75,7 +76,7 @@ func TestAccount_Save(t *testing.T) {
|
||||
err = model.Save(UpdateForm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "NewName", model.AccName)
|
||||
@@ -94,18 +95,18 @@ func TestAccount_Delete(t *testing.T) {
|
||||
accountForm, err := form.NewAccount(account)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
model, err := CreateAccount(accountForm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = model.Delete()
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
// TODO how to assert deletion?
|
||||
|
||||
@@ -121,18 +122,18 @@ func TestAccount_Directories(t *testing.T) {
|
||||
accountForm, err := form.NewAccount(account)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
model, err := CreateAccount(accountForm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
result, err := model.Directories()
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.NotEmpty(t, result.Abs())
|
||||
assert.Contains(t, result.Abs(), "/Photos")
|
||||
@@ -146,18 +147,18 @@ func TestAccount_Directories(t *testing.T) {
|
||||
accountForm, err := form.NewAccount(account)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
model, err := CreateAccount(accountForm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
result, err := model.Directories()
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Empty(t, result.Abs())
|
||||
|
||||
@@ -75,13 +75,13 @@ func TestAlbum_Save(t *testing.T) {
|
||||
albumForm, err := form.NewAlbum(album2)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = album.Save(albumForm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "New name", album.AlbumName)
|
||||
|
||||
@@ -9,7 +9,7 @@ func TestDescription_FirstOrCreate(t *testing.T) {
|
||||
description := &Description{PhotoID: 123, PhotoDescription: ""}
|
||||
err := description.FirstOrCreate()
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ package entity
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
@@ -19,7 +18,6 @@ import (
|
||||
)
|
||||
|
||||
var log = event.Log
|
||||
var resetFixturesOnce sync.Once
|
||||
|
||||
func logError(result *gorm.DB) {
|
||||
if result.Error != nil {
|
||||
@@ -74,6 +72,18 @@ func (list Types) WaitForMigration() {
|
||||
}
|
||||
}
|
||||
|
||||
// Truncate removes all data from tables without dropping them.
|
||||
func (list Types) Truncate() {
|
||||
for name := range list {
|
||||
if err := Db().Raw(fmt.Sprintf("TRUNCATE TABLE `%s`", name)).Scan(&struct{}{}).Error; err == nil {
|
||||
log.Debugf("entity: removed all data from %s", name)
|
||||
break
|
||||
} else {
|
||||
log.Debugf("entity: %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Drop migrates all database tables of registered entities.
|
||||
func (list Types) Migrate() {
|
||||
for _, entity := range list {
|
||||
@@ -98,40 +108,31 @@ func (list Types) Drop() {
|
||||
}
|
||||
}
|
||||
|
||||
// MigrateDb creates all tables and inserts default entities as needed.
|
||||
func MigrateDb() {
|
||||
Entities.Migrate()
|
||||
Entities.WaitForMigration()
|
||||
|
||||
// Creates default database entries for test and production.
|
||||
func CreateDefaultFixtures() {
|
||||
CreateUnknownPlace()
|
||||
CreateUnknownCountry()
|
||||
CreateUnknownCamera()
|
||||
CreateUnknownLens()
|
||||
}
|
||||
|
||||
// DropTables drops database tables for all known entities.
|
||||
func DropTables() {
|
||||
Entities.Drop()
|
||||
// MigrateDb creates all tables and inserts default entities as needed.
|
||||
func MigrateDb() {
|
||||
Entities.Migrate()
|
||||
Entities.WaitForMigration()
|
||||
|
||||
// wait for changes to be written to disk
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
CreateDefaultFixtures()
|
||||
}
|
||||
|
||||
// ResetDb drops database tables for all known entities and re-creates them with fixtures.
|
||||
func ResetDb(testFixtures bool) {
|
||||
DropTables()
|
||||
MigrateDb()
|
||||
// ResetTestFixtures drops database tables for all known entities and re-creates them with fixtures.
|
||||
func ResetTestFixtures() {
|
||||
Entities.Migrate()
|
||||
Entities.WaitForMigration()
|
||||
Entities.Truncate()
|
||||
|
||||
CreateDefaultFixtures()
|
||||
|
||||
if testFixtures {
|
||||
CreateTestFixtures()
|
||||
}
|
||||
}
|
||||
|
||||
// InitTestFixtures resets the database and test fixtures once.
|
||||
func InitTestFixtures() {
|
||||
resetFixturesOnce.Do(func() {
|
||||
ResetDb(true)
|
||||
})
|
||||
}
|
||||
|
||||
// InitTestDb connects to and completely initializes the test database incl fixtures.
|
||||
@@ -146,7 +147,7 @@ func InitTestDb(dsn string) *Gorm {
|
||||
}
|
||||
|
||||
SetDbProvider(db)
|
||||
InitTestFixtures()
|
||||
ResetTestFixtures()
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package entity
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -17,7 +18,7 @@ func TestMain(m *testing.M) {
|
||||
panic("database dsn is empty")
|
||||
}
|
||||
|
||||
db := InitTestDb(dsn)
|
||||
db := InitTestDb(strings.Replace(dsn, "/photoprism", "/entity", 1))
|
||||
|
||||
code := m.Run()
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ func TestFirstFileByHash(t *testing.T) {
|
||||
t.Run("existing file", func(t *testing.T) {
|
||||
f, err := FirstFileByHash("2cad9168fa6acc5c5c2965ddf6ec465ca42fd818")
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, uint(0xf4240), f.ID)
|
||||
})
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestLabel_Update(t *testing.T) {
|
||||
|
||||
err := Label.Update(*classifyLabel)
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 5, Label.LabelPriority)
|
||||
@@ -89,7 +89,7 @@ func TestLabel_Update(t *testing.T) {
|
||||
|
||||
err := Label.Update(*classifyLabel)
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 5, Label.LabelPriority)
|
||||
@@ -109,7 +109,7 @@ func TestLabel_Update(t *testing.T) {
|
||||
|
||||
err := Label.Update(*classifyLabel)
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 5, Label.LabelPriority)
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestPhotoLabel_Save(t *testing.T) {
|
||||
photoLabel := NewPhotoLabel(13, 1000, 99, "image")
|
||||
err := photoLabel.Save()
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -87,13 +87,13 @@ func TestPhoto_Save(t *testing.T) {
|
||||
|
||||
err := photo.Save()
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
t.Run("existing photo", func(t *testing.T) {
|
||||
err := PhotoFixture19800101_000002_D640C559.Save()
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ func TestNewAccount(t *testing.T) {
|
||||
r, err := NewAccount(account)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "Foo", r.AccName)
|
||||
|
||||
@@ -26,7 +26,7 @@ func TestNewAlbum(t *testing.T) {
|
||||
r, err := NewAlbum(album)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "Foo", r.AlbumName)
|
||||
|
||||
@@ -17,7 +17,7 @@ func TestNewPhoto(t *testing.T) {
|
||||
r, err := NewPhoto(photo)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("error")
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, time.Date(2008, 1, 1, 2, 0, 0, 0, time.UTC), r.TakenAt)
|
||||
|
||||
@@ -2,6 +2,7 @@ package query
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
@@ -18,7 +19,7 @@ func TestMain(m *testing.M) {
|
||||
panic("database dsn is empty")
|
||||
}
|
||||
|
||||
db := entity.InitTestDb(dsn)
|
||||
db := entity.InitTestDb(strings.Replace(dsn, "/photoprism", "/query", 1))
|
||||
|
||||
code := m.Run()
|
||||
|
||||
|
||||
9
scripts/test-db.sql
Normal file
9
scripts/test-db.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
CREATE DATABASE IF NOT EXISTS api;
|
||||
CREATE DATABASE IF NOT EXISTS config;
|
||||
CREATE DATABASE IF NOT EXISTS entity;
|
||||
CREATE DATABASE IF NOT EXISTS photoprism;
|
||||
CREATE DATABASE IF NOT EXISTS query;
|
||||
CREATE DATABASE IF NOT EXISTS remote;
|
||||
CREATE DATABASE IF NOT EXISTS service;
|
||||
CREATE DATABASE IF NOT EXISTS workers;
|
||||
CREATE DATABASE IF NOT EXISTS acceptance;
|
||||
Reference in New Issue
Block a user