mirror of
https://github.com/photoprism/photoprism.git
synced 2026-07-17 16:49:04 +00:00
Tests: Improve isolation and add fixes #5263
* Tests: fix random selection of deleted record causing test failure * Tests: fix test folders being left after test * Tests: ensure that required records are available * Tests: make each package execute against it's own testdata folder to ensure no interpackage test failures * Tests: add unit tests of CleanupTestFolder * Tests: Allow defer in TestMain * Tests: rename testMain to runTestMain
This commit is contained in:
parent
79a3d36334
commit
b6687b6c29
36 changed files with 402 additions and 241 deletions
|
|
@ -15,7 +15,12 @@ import (
|
|||
var assetsPath = fs.Abs("../../../assets")
|
||||
var samplesPath = filepath.Join(assetsPath, "samples")
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
// Init test logger.
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
|
@ -27,7 +32,5 @@ func TestMain(m *testing.M) {
|
|||
ServiceUri = ""
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/http/header"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
// Init test logger.
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
|
@ -31,6 +36,15 @@ func TestMain(m *testing.M) {
|
|||
|
||||
// Init test config.
|
||||
c := config.TestConfig()
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
get.SetConfig(c)
|
||||
|
||||
// Increase the login and authentication rate limits for testing so the many
|
||||
|
|
@ -39,16 +53,7 @@ func TestMain(m *testing.M) {
|
|||
limiter.Auth = limiter.NewLimit(1, 10000)
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
type CloseableResponseRecorder struct {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ func TestRemoveFromAlbumCoverCache(t *testing.T) {
|
|||
cache.Flush()
|
||||
|
||||
var album entity.Album
|
||||
if err := query.UnscopedDb().Where("album_type = ? AND thumb_src = ?", entity.AlbumManual, entity.SrcAuto).First(&album).Error; err != nil {
|
||||
if err := query.Db().Where("album_type = ? AND thumb_src = ?", entity.AlbumManual, entity.SrcAuto).First(&album).Error; err != nil {
|
||||
t.Skipf("no auto-managed manual album available: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,12 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
// Init test logger.
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
|
@ -18,7 +23,5 @@ func TestMain(m *testing.M) {
|
|||
AllowedPaths = append(AllowedPaths, fs.Abs("./testdata"))
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,19 +11,25 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
// Init test logger.
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
event.AuditLog = log
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
// Run unit tests.
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func newTestConfig(t *testing.T) *cfg.Config {
|
||||
|
|
|
|||
|
|
@ -9,14 +9,17 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/event"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
// Init test logger.
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
event.AuditLog = log
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,21 +11,25 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
event.AuditLog = log
|
||||
|
||||
c := config.TestConfig()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,12 @@ import (
|
|||
// "config: database not connected" during test runs, consider moving shutdown
|
||||
// behavior behind an interface or gating it for tests.
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
_ = os.Setenv("TF_CPP_MIN_LOG_LEVEL", "3")
|
||||
|
||||
log = logrus.StandardLogger()
|
||||
|
|
@ -35,8 +40,18 @@ func TestMain(m *testing.M) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
c := config.NewMinimalTestConfigWithDb("commands", tempDir)
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
get.SetConfig(c)
|
||||
|
||||
// Keep DB connection open for the duration of this package's tests to
|
||||
|
|
@ -55,18 +70,7 @@ func TestMain(m *testing.M) {
|
|||
}
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
if err = c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
_ = os.RemoveAll(tempDir)
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
// SetEnvForTest sets an environment variable and restores its original value after the test.
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ func createFakeYtDlp(t *testing.T) string {
|
|||
if derr != nil {
|
||||
t.Fatalf("failed to create temp dir: %v", derr)
|
||||
}
|
||||
t.Cleanup(func() { os.RemoveAll(dir) })
|
||||
path := filepath.Join(dir, "yt-dlp")
|
||||
if runtime.GOOS == "windows" {
|
||||
// Not needed in CI/dev container. Keep simple stub.
|
||||
|
|
|
|||
|
|
@ -638,6 +638,7 @@ func TestConfig_ClientSessionConfig(t *testing.T) {
|
|||
f := cfg.Settings.Features
|
||||
assert.Equal(t, adminFeatures, f)
|
||||
})
|
||||
c.CleanupTestFolder()
|
||||
}
|
||||
|
||||
func TestConfig_Flags(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -21,23 +21,27 @@ func init() {
|
|||
hub.ApplyTestConfig()
|
||||
}
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
_ = os.Setenv("PHOTOPRISM_TEST", "true")
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
||||
c := TestConfig()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestNewConfig(t *testing.T) {
|
||||
|
|
@ -316,7 +320,7 @@ func TestConfig_ThemePath(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfig_Serial(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
c := TestConfig() // Use complete test context, as NewConfig may not have the required file.
|
||||
|
||||
result := c.Serial()
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -226,6 +227,13 @@ func TestConfig() *Config {
|
|||
return testConfig
|
||||
}
|
||||
|
||||
// OnceTestConfig attempts to set testConfig if it hasn't already been done.
|
||||
func OnceTestConfig(c *Config) {
|
||||
// If this is the 1st call to NewTestConfig, then cache it.
|
||||
// This is required for /internal/photoprism tests.
|
||||
testConfigOnce.Do(func() { testConfig = c })
|
||||
}
|
||||
|
||||
// NewMinimalTestConfig creates a lightweight test Config (no DB, minimal filesystem).
|
||||
//
|
||||
// Not suitable for tests requiring a database or pre-created storage directories.
|
||||
|
|
@ -314,15 +322,30 @@ func NewIsolatedTestConfig(dbName, dataPath string, createDirs bool) *Config {
|
|||
|
||||
// NewTestConfig initializes test data so required directories exist before tests run.
|
||||
// See AGENTS.md (Test Data & Fixtures) for guidance.
|
||||
// This now creates an isolated set of folders to ensure that cross package testing does not clash.
|
||||
// You should use os.RemoveAll(c.StoragePath()) to remove the isolated folder created (assuming c := NewTestConfig("test")).
|
||||
func NewTestConfig(dbName string) *Config {
|
||||
defer log.Debug(capture.Time(time.Now(), "config: new test config created"))
|
||||
|
||||
testConfigMutex.Lock()
|
||||
defer testConfigMutex.Unlock()
|
||||
|
||||
storagePath := os.Getenv("PHOTOPRISM_STORAGE_PATH")
|
||||
if storagePath == "" {
|
||||
storagePath = fs.Abs("../../storage")
|
||||
}
|
||||
|
||||
var tp string
|
||||
var err error
|
||||
if tp, err = os.MkdirTemp(storagePath, "test-photoprism-*"); err != nil {
|
||||
log.Fatalf("config: %s", err.Error())
|
||||
}
|
||||
|
||||
tp = filepath.Join(tp, fs.TestdataDir)
|
||||
|
||||
c := &Config{
|
||||
cliCtx: CliTestContext(),
|
||||
options: NewTestOptions(dbName),
|
||||
options: NewTestOptionsForPath(dbName, tp),
|
||||
token: rnd.Base36(8),
|
||||
cache: gc.New(time.Second, time.Minute),
|
||||
}
|
||||
|
|
@ -611,3 +634,21 @@ func (c *Config) AssertTestData(t *testing.T) {
|
|||
reportErr("SidecarPath")
|
||||
}
|
||||
}
|
||||
|
||||
// CleanupTestFolder uses RemoveAll to remove the storage path above testdata.
|
||||
func (c *Config) CleanupTestFolder() {
|
||||
if c.options == nil {
|
||||
log.Warn("config: c.options is nil in CleanupTestFolder")
|
||||
return
|
||||
}
|
||||
td := c.StoragePath()
|
||||
if strings.HasSuffix(td, "/testdata") && strings.Contains(td, "test-photoprism") {
|
||||
td = strings.TrimSuffix(td, "/testdata")
|
||||
if err := os.RemoveAll(td); err != nil {
|
||||
log.Fatalf("config: %s (cleantestfolder)", err.Error())
|
||||
}
|
||||
log.Debugf("config: cleaned up %s", td)
|
||||
} else {
|
||||
log.Warnf("config: %s not cleaned up", td)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
|
|
@ -57,3 +59,47 @@ func TestNewTestErrorConfig(t *testing.T) {
|
|||
|
||||
assert.IsType(t, &gorm.DB{}, db)
|
||||
}
|
||||
|
||||
func TestCleanupTestFolder(t *testing.T) {
|
||||
t.Run("OptionsNil", func(t *testing.T) {
|
||||
// Setup and capture log output
|
||||
buffer := bytes.Buffer{}
|
||||
log.SetOutput(&buffer)
|
||||
|
||||
var c Config
|
||||
c.CleanupTestFolder()
|
||||
|
||||
// Reset logger
|
||||
log.SetOutput(os.Stdout)
|
||||
|
||||
assert.Contains(t, buffer.String(), "config: c.options is nil in CleanupTestFolder")
|
||||
})
|
||||
|
||||
t.Run("NotExpectedPath", func(t *testing.T) {
|
||||
// Setup and capture log output
|
||||
buffer := bytes.Buffer{}
|
||||
log.SetOutput(&buffer)
|
||||
|
||||
c := Config{options: &Options{StoragePath: "/tmp/photoprism/testdata"}}
|
||||
c.CleanupTestFolder()
|
||||
|
||||
// Reset logger
|
||||
log.SetOutput(os.Stdout)
|
||||
|
||||
assert.Contains(t, buffer.String(), "config: /tmp/photoprism/testdata not cleaned up")
|
||||
})
|
||||
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
// Setup and capture log output
|
||||
buffer := bytes.Buffer{}
|
||||
log.SetOutput(&buffer)
|
||||
|
||||
c := Config{options: &Options{StoragePath: "/tmp/photoprism/test-photoprism-1394931550/testdata"}}
|
||||
c.CleanupTestFolder()
|
||||
|
||||
// Reset logger
|
||||
log.SetOutput(os.Stdout)
|
||||
|
||||
assert.Contains(t, buffer.String(), "config: cleaned up /tmp/photoprism/test-photoprism-1394931550")
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,26 +11,27 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
event.AuditLog = log
|
||||
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
db := InitTestDb(
|
||||
os.Getenv("PHOTOPRISM_TEST_DRIVER"),
|
||||
os.Getenv("PHOTOPRISM_TEST_DSN"))
|
||||
defer db.Close()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
db.Close()
|
||||
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestTypeString(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ func TestUpdateAlbumManualCovers(t *testing.T) {
|
|||
func TestUpdateAlbumManualCoversFiltered(t *testing.T) {
|
||||
var album entity.Album
|
||||
|
||||
assert.NoError(t, UpdateAlbumManualCovers())
|
||||
if err := UnscopedDb().Where("album_type = ? AND thumb_src = ? AND thumb <> ''", entity.AlbumManual, entity.SrcAuto).First(&album).Error; err != nil {
|
||||
t.Skipf("no auto-managed manual album available: %v", err)
|
||||
}
|
||||
|
|
@ -46,6 +47,7 @@ func TestUpdateAlbumFolderCovers(t *testing.T) {
|
|||
func TestUpdateAlbumFolderCoversFiltered(t *testing.T) {
|
||||
var album entity.Album
|
||||
|
||||
assert.NoError(t, UpdateAlbumFolderCovers())
|
||||
if err := UnscopedDb().Where("album_type = ? AND thumb_src = ? AND album_path <> '' AND thumb <> ''", entity.AlbumFolder, entity.SrcAuto).First(&album).Error; err != nil {
|
||||
t.Skipf("no auto-managed folder album available: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,25 +22,26 @@ func (p staticDbProvider) Db() *gorm.DB {
|
|||
return p.db
|
||||
}
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
db := entity.InitTestDb(
|
||||
os.Getenv("PHOTOPRISM_TEST_DRIVER"),
|
||||
os.Getenv("PHOTOPRISM_TEST_DSN"))
|
||||
defer db.Close()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
db.Close()
|
||||
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestDbDialect(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -10,23 +10,24 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
db := entity.InitTestDb(
|
||||
os.Getenv("PHOTOPRISM_TEST_DRIVER"),
|
||||
os.Getenv("PHOTOPRISM_TEST_DSN"))
|
||||
|
||||
defer db.Close()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,14 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
||||
code := m.Run()
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,12 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
event.AuditLog = log
|
||||
|
|
@ -22,18 +27,17 @@ func TestMain(m *testing.M) {
|
|||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
c := config.TestConfig()
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
get.SetConfig(c)
|
||||
photoprism.SetConfig(c)
|
||||
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,19 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/mutex"
|
||||
"github.com/photoprism/photoprism/internal/photoprism"
|
||||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain configures shared state for the batch action tests.
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
// runTestMain configures shared state for the batch action tests.
|
||||
func runTestMain(m *testing.M) (code int) {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
event.AuditLog = log
|
||||
|
|
@ -23,18 +29,18 @@ func TestMain(m *testing.M) {
|
|||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
c := config.TestConfig()
|
||||
|
||||
get.SetConfig(c)
|
||||
photoprism.SetConfig(c)
|
||||
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
// Prevent UpdateCountsAsync from causing the test suite to fail due to the database closing before the goroutine has finished.
|
||||
mutex.Index.Lock()
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
os.Exit(code)
|
||||
get.SetConfig(c)
|
||||
photoprism.SetConfig(c)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,27 +8,29 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) (code int) {
|
||||
tempDir, err := os.MkdirTemp("", "internal-photoprism-get")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
c := config.NewMinimalTestConfigWithDb("test", tempDir)
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
SetConfig(c)
|
||||
|
||||
code := m.Run()
|
||||
|
||||
if err = c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
if err = os.RemoveAll(tempDir); err != nil {
|
||||
log.Errorf("remove temp dir: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package photoprism
|
|||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -11,51 +10,26 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runMain(m))
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
// runMain initializes package-level test state and returns the test exit code.
|
||||
func runMain(m *testing.M) int {
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
||||
// Isolate package fixtures per process so parallel package test runs do not
|
||||
// race on shared storage/testdata directories.
|
||||
testRoot, err := os.MkdirTemp("", "photoprism-test-*")
|
||||
if err != nil {
|
||||
log.Errorf("create test root: %v", err)
|
||||
return 1
|
||||
}
|
||||
defer os.RemoveAll(testRoot)
|
||||
|
||||
if err = os.Setenv("PHOTOPRISM_STORAGE_PATH", filepath.Join(testRoot, "storage")); err != nil {
|
||||
log.Errorf("set PHOTOPRISM_STORAGE_PATH: %v", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
if err = os.Setenv("PHOTOPRISM_TEST_DRIVER", "sqlite"); err != nil {
|
||||
log.Errorf("set PHOTOPRISM_TEST_DRIVER: %v", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
testDsn := filepath.Join(testRoot, "photoprism-test.db") + "?_busy_timeout=5000"
|
||||
if err = os.Setenv("PHOTOPRISM_TEST_DSN", testDsn); err != nil {
|
||||
log.Errorf("set PHOTOPRISM_TEST_DSN: %v", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
c := config.NewTestConfig("photoprism")
|
||||
config.OnceTestConfig(c)
|
||||
SetConfig(c)
|
||||
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err = c.CloseDb(); err != nil {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ func TestThumb_Filename(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.True(t, strings.HasSuffix(filename, "/storage/testdata/cache/_tmp/9/9/9/99988_150x150_fit.jpg"))
|
||||
assert.True(t, strings.HasSuffix(filename, "/testdata/cache/_tmp/9/9/9/99988_150x150_fit.jpg"))
|
||||
})
|
||||
t.Run("InvalidHash", func(t *testing.T) {
|
||||
_, err := thumb.FileName("999", thumbsPath, 150, 150, thumb.ResampleFit, thumb.ResampleNearestNeighbor)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,12 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) (code int) {
|
||||
// Init test logger.
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
|
@ -24,20 +29,20 @@ func TestMain(m *testing.M) {
|
|||
|
||||
// Init test config.
|
||||
c := config.TestConfig()
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
get.SetConfig(c)
|
||||
|
||||
// Increase login rate limit for testing.
|
||||
limiter.Login = limiter.NewLimit(1, 10000)
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,27 @@ import (
|
|||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) (code int) {
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
c := config.TestConfig()
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
c.CloseDb()
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
os.Exit(code)
|
||||
// Run unit tests.
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,16 +7,18 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain ensures SQLite test DB artifacts are purged after the suite runs.
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
// TestMain ensures SQLite test DB artifacts are purged after the suite runs.
|
||||
func runTestMain(m *testing.M) int {
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,16 +7,18 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain ensures SQLite test DB artifacts are purged after the suite runs.
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
// TestMain ensures SQLite test DB artifacts are purged after the suite runs.
|
||||
func runTestMain(m *testing.M) int {
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,18 +13,20 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
// TestMain ensures SQLite test DB artifacts are purged after the suite runs.
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
// TestMain ensures SQLite test DB artifacts are purged after the suite runs.
|
||||
func runTestMain(m *testing.M) int {
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
defer fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestClientRegistry_GetAndDelete(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -13,15 +13,18 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
||||
ApplyTestConfig()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
// Token returns a random token with length of up to 10 characters.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) (code int) {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
||||
|
|
@ -20,21 +25,19 @@ func TestMain(m *testing.M) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
c := config.NewMinimalTestConfigWithDb("avatar", tempDir)
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
get.SetConfig(c)
|
||||
photoprism.SetConfig(c)
|
||||
|
||||
code := m.Run()
|
||||
|
||||
if err = c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
_ = os.RemoveAll(tempDir)
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,21 +10,23 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/event"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
event.AuditLog = log
|
||||
|
||||
code := m.Run()
|
||||
|
||||
Shutdown()
|
||||
|
||||
defer Shutdown()
|
||||
// Remove generated test files and folders.
|
||||
_ = os.RemoveAll("testdata/1")
|
||||
_ = os.RemoveAll("testdata/cache")
|
||||
_ = os.RemoveAll("testdata/vips")
|
||||
defer os.RemoveAll("testdata/1")
|
||||
defer os.RemoveAll("testdata/cache")
|
||||
defer os.RemoveAll("testdata/vips")
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -10,23 +10,30 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) (code int) {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
|
||||
// Remove temporary SQLite files before running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
c := config.TestConfig()
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
os.Exit(code)
|
||||
// Run unit tests.
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestStart(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,12 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) (code int) {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
event.AuditLog = log
|
||||
|
|
@ -22,19 +27,18 @@ func TestMain(m *testing.M) {
|
|||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
c := config.TestConfig()
|
||||
defer c.CleanupTestFolder()
|
||||
defer func() {
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
}()
|
||||
|
||||
get.SetConfig(c)
|
||||
photoprism.SetConfig(c)
|
||||
|
||||
// Run unit tests.
|
||||
code := m.Run()
|
||||
|
||||
if err := c.CloseDb(); err != nil {
|
||||
log.Warnf("close db: %v", err)
|
||||
}
|
||||
|
||||
// Remove temporary SQLite files after running the tests.
|
||||
fs.PurgeTestDbFiles(".", false)
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,6 @@ func TestCachePath(t *testing.T) {
|
|||
assert.Equal(t, expected, result)
|
||||
assert.DirExists(t, expected)
|
||||
|
||||
_ = os.Remove(expected)
|
||||
_ = os.RemoveAll(filepath.Join(os.TempDir(), ns))
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,16 +13,19 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
if insensitive, err := CaseInsensitive(os.TempDir()); err != nil {
|
||||
fmt.Println(err)
|
||||
} else if insensitive {
|
||||
IgnoreCase()
|
||||
}
|
||||
|
||||
code := m.Run()
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
// newTestServer creates an HTTP test server and registers cleanup.
|
||||
|
|
|
|||
|
|
@ -8,12 +8,15 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestMain executes runTestMain returning it's results. It is done this way so that defer can be used to cleanup.
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(runTestMain(m))
|
||||
}
|
||||
|
||||
func runTestMain(m *testing.M) int {
|
||||
gotext.Configure(localeDir, string(locale), "default")
|
||||
|
||||
code := m.Run()
|
||||
|
||||
os.Exit(code)
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func TestMsg(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue