diff --git a/Dockerfile b/Dockerfile index 7cee0f32d3..cb536b0bde 100644 --- a/Dockerfile +++ b/Dockerfile @@ -76,5 +76,6 @@ ENV GITEA_CUSTOM=/data/gitea VOLUME ["/data"] +# HINT: HEALTH-CHECK-ENDPOINT: don't use HEALTHCHECK, search this hint keyword for more information ENTRYPOINT ["/usr/bin/entrypoint"] CMD ["/usr/bin/s6-svscan", "/etc/s6"] diff --git a/Dockerfile.rootless b/Dockerfile.rootless index 8a6fa587e9..e4ba3d2fba 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -77,5 +77,6 @@ ENV HOME="/var/lib/gitea/git" VOLUME ["/var/lib/gitea", "/etc/gitea"] WORKDIR /var/lib/gitea +# HINT: HEALTH-CHECK-ENDPOINT: don't use HEALTHCHECK, search this hint keyword for more information ENTRYPOINT ["/usr/bin/dumb-init", "--", "/usr/local/bin/docker-entrypoint.sh"] CMD [] diff --git a/Makefile b/Makefile index 49474b0c5c..0a5f174d6d 100644 --- a/Makefile +++ b/Makefile @@ -489,11 +489,11 @@ generate-ini-sqlite: .PHONY: test-sqlite test-sqlite: integrations.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test + GITEA_TEST_CONF=tests/sqlite.ini ./integrations.sqlite.test .PHONY: test-sqlite\#% test-sqlite\#%: integrations.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*) + GITEA_TEST_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*) .PHONY: test-sqlite-migration test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test @@ -510,11 +510,11 @@ generate-ini-mysql: .PHONY: test-mysql test-mysql: integrations.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test + GITEA_TEST_CONF=tests/mysql.ini ./integrations.mysql.test .PHONY: test-mysql\#% test-mysql\#%: integrations.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*) + GITEA_TEST_CONF=tests/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*) .PHONY: test-mysql-migration test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test @@ -533,11 +533,11 @@ generate-ini-pgsql: .PHONY: test-pgsql test-pgsql: integrations.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test + GITEA_TEST_CONF=tests/pgsql.ini ./integrations.pgsql.test .PHONY: test-pgsql\#% test-pgsql\#%: integrations.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*) + GITEA_TEST_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*) .PHONY: test-pgsql-migration test-pgsql-migration: migrations.pgsql.test migrations.individual.pgsql.test @@ -554,11 +554,11 @@ generate-ini-mssql: .PHONY: test-mssql test-mssql: integrations.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test + GITEA_TEST_CONF=tests/mssql.ini ./integrations.mssql.test .PHONY: test-mssql\#% test-mssql\#%: integrations.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*) + GITEA_TEST_CONF=tests/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*) .PHONY: test-mssql-migration test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test @@ -577,59 +577,59 @@ test-e2e: test-e2e-sqlite .PHONY: test-e2e-sqlite test-e2e-sqlite: playwright e2e.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./e2e.sqlite.test + GITEA_TEST_CONF=tests/sqlite.ini ./e2e.sqlite.test .PHONY: test-e2e-sqlite\#% test-e2e-sqlite\#%: playwright e2e.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./e2e.sqlite.test -test.run TestE2e/$* + GITEA_TEST_CONF=tests/sqlite.ini ./e2e.sqlite.test -test.run TestE2e/$* .PHONY: test-e2e-mysql test-e2e-mysql: playwright e2e.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test + GITEA_TEST_CONF=tests/mysql.ini ./e2e.mysql.test .PHONY: test-e2e-mysql\#% test-e2e-mysql\#%: playwright e2e.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test -test.run TestE2e/$* + GITEA_TEST_CONF=tests/mysql.ini ./e2e.mysql.test -test.run TestE2e/$* .PHONY: test-e2e-pgsql test-e2e-pgsql: playwright e2e.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test + GITEA_TEST_CONF=tests/pgsql.ini ./e2e.pgsql.test .PHONY: test-e2e-pgsql\#% test-e2e-pgsql\#%: playwright e2e.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test -test.run TestE2e/$* + GITEA_TEST_CONF=tests/pgsql.ini ./e2e.pgsql.test -test.run TestE2e/$* .PHONY: test-e2e-mssql test-e2e-mssql: playwright e2e.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./e2e.mssql.test + GITEA_TEST_CONF=tests/mssql.ini ./e2e.mssql.test .PHONY: test-e2e-mssql\#% test-e2e-mssql\#%: playwright e2e.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./e2e.mssql.test -test.run TestE2e/$* + GITEA_TEST_CONF=tests/mssql.ini ./e2e.mssql.test -test.run TestE2e/$* .PHONY: bench-sqlite bench-sqlite: integrations.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . + GITEA_TEST_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . .PHONY: bench-mysql bench-mysql: integrations.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . + GITEA_TEST_CONF=tests/mysql.ini ./integrations.mysql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . .PHONY: bench-mssql bench-mssql: integrations.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . + GITEA_TEST_CONF=tests/mssql.ini ./integrations.mssql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . .PHONY: bench-pgsql bench-pgsql: integrations.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . + GITEA_TEST_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . .PHONY: integration-test-coverage integration-test-coverage: integrations.cover.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out + GITEA_TEST_CONF=tests/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out .PHONY: integration-test-coverage-sqlite integration-test-coverage-sqlite: integrations.cover.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out + GITEA_TEST_CONF=tests/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out integrations.mysql.test: git-check $(GO_SOURCES) $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql.test @@ -652,54 +652,54 @@ integrations.cover.sqlite.test: git-check $(GO_SOURCES) .PHONY: migrations.mysql.test migrations.mysql.test: $(GO_SOURCES) generate-ini-mysql $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.mysql.test + GITEA_TEST_CONF=tests/mysql.ini ./migrations.mysql.test .PHONY: migrations.pgsql.test migrations.pgsql.test: $(GO_SOURCES) generate-ini-pgsql $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./migrations.pgsql.test + GITEA_TEST_CONF=tests/pgsql.ini ./migrations.pgsql.test .PHONY: migrations.mssql.test migrations.mssql.test: $(GO_SOURCES) generate-ini-mssql $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mssql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./migrations.mssql.test + GITEA_TEST_CONF=tests/mssql.ini ./migrations.mssql.test .PHONY: migrations.sqlite.test migrations.sqlite.test: $(GO_SOURCES) generate-ini-sqlite $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)' - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.sqlite.test + GITEA_TEST_CONF=tests/sqlite.ini ./migrations.sqlite.test .PHONY: migrations.individual.mysql.test migrations.individual.mysql.test: $(GO_SOURCES) - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES) + GITEA_TEST_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES) .PHONY: migrations.individual.sqlite.test\#% migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* + GITEA_TEST_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* .PHONY: migrations.individual.pgsql.test migrations.individual.pgsql.test: $(GO_SOURCES) - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES) + GITEA_TEST_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES) .PHONY: migrations.individual.pgsql.test\#% migrations.individual.pgsql.test\#%: $(GO_SOURCES) generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* + GITEA_TEST_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* .PHONY: migrations.individual.mssql.test migrations.individual.mssql.test: $(GO_SOURCES) generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES) + GITEA_TEST_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES) .PHONY: migrations.individual.mssql.test\#% migrations.individual.mssql.test\#%: $(GO_SOURCES) generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* + GITEA_TEST_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* .PHONY: migrations.individual.sqlite.test migrations.individual.sqlite.test: $(GO_SOURCES) generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES) + GITEA_TEST_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES) .PHONY: migrations.individual.sqlite.test\#% migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* + GITEA_TEST_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* e2e.mysql.test: $(GO_SOURCES) $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test @@ -747,7 +747,7 @@ security-check: $(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ) ifneq ($(and $(STATIC),$(findstring pam,$(TAGS))),) - $(error pam support set via TAGS doesn't support static builds) + $(error pam support set via TAGS does not support static builds) endif CGO_ENABLED="$(CGO_ENABLED)" CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(EXTLDFLAGS) $(LDFLAGS)' -o $@ diff --git a/cmd/main.go b/cmd/main.go index 203799f02f..2ee00382d7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -149,7 +149,7 @@ func NewMainApp(appVer AppVersion) *cli.Command { app.Commands = append(app.Commands, subCmdWithConfig...) app.Commands = append(app.Commands, subCmdStandalone...) - setting.InitGiteaEnvVars() + setting.UnsetUnnecessaryEnvVars() return app } diff --git a/cmd/main_test.go b/cmd/main_test.go index 69ea1237c6..b1f6bb3ba9 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -157,6 +157,7 @@ func TestCliCmd(t *testing.T) { for _, c := range cases { t.Run(c.cmd, func(t *testing.T) { + defer test.MockVariableValue(&setting.InstallLock, false)() app := newTestApp(cli.Command{ Action: func(ctx context.Context, cmd *cli.Command) error { _, _ = fmt.Fprint(cmd.Root().Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf)) @@ -170,7 +171,10 @@ func TestCliCmd(t *testing.T) { r, err := runTestApp(app, args...) assert.NoError(t, err, c.cmd) assert.NotEmpty(t, c.exp, c.cmd) - assert.Contains(t, r.Stdout, c.exp, c.cmd) + if !assert.Contains(t, r.Stdout, c.exp, c.cmd) { + t.Log("Full output:\n" + r.Stdout) + t.Log("Expected:\n" + c.exp) + } }) } } diff --git a/models/db/engine_init.go b/models/db/engine_init.go index f26189b805..ef5db3ff5e 100644 --- a/models/db/engine_init.go +++ b/models/db/engine_init.go @@ -57,7 +57,7 @@ func InitEngine(ctx context.Context) error { xe, err := newXORMEngine() if err != nil { if strings.Contains(err.Error(), "SQLite3 support") { - return fmt.Errorf(`sqlite3 requires: -tags sqlite,sqlite_unlock_notify%s%w`, "\n", err) + return fmt.Errorf("sqlite3 requires: -tags sqlite,sqlite_unlock_notify\n%w", err) } return fmt.Errorf("failed to connect to database: %w", err) } diff --git a/models/migrations/base/db.go b/models/migrations/base/db.go index 479a46379c..3b8f0e00a0 100644 --- a/models/migrations/base/db.go +++ b/models/migrations/base/db.go @@ -5,21 +5,14 @@ package base import ( "context" - "database/sql" "errors" "fmt" - "os" - "path" "reflect" "regexp" "strings" - "time" - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" "xorm.io/xorm" "xorm.io/xorm/schemas" @@ -515,114 +508,3 @@ func ModifyColumn(x *xorm.Engine, tableName string, col *schemas.Column) error { } return nil } - -func removeAllWithRetry(dir string) error { - var err error - for range 20 { - err = os.RemoveAll(dir) - if err == nil { - break - } - time.Sleep(100 * time.Millisecond) - } - return err -} - -func newXORMEngine() (*xorm.Engine, error) { - if err := db.InitEngine(context.Background()); err != nil { - return nil, err - } - x := unittest.GetXORMEngine() - return x, nil -} - -func deleteDB() error { - switch { - case setting.Database.Type.IsSQLite3(): - if err := util.Remove(setting.Database.Path); err != nil { - return err - } - return os.MkdirAll(path.Dir(setting.Database.Path), os.ModePerm) - - case setting.Database.Type.IsMySQL(): - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/", - setting.Database.User, setting.Database.Passwd, setting.Database.Host)) - if err != nil { - return err - } - defer db.Close() - - if _, err = db.Exec("DROP DATABASE IF EXISTS " + setting.Database.Name); err != nil { - return err - } - - if _, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + setting.Database.Name); err != nil { - return err - } - return nil - case setting.Database.Type.IsPostgreSQL(): - db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/?sslmode=%s", - setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.SSLMode)) - if err != nil { - return err - } - defer db.Close() - - if _, err = db.Exec("DROP DATABASE IF EXISTS " + setting.Database.Name); err != nil { - return err - } - - if _, err = db.Exec("CREATE DATABASE " + setting.Database.Name); err != nil { - return err - } - db.Close() - - // Check if we need to setup a specific schema - if len(setting.Database.Schema) != 0 { - db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s", - setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode)) - if err != nil { - return err - } - defer db.Close() - - schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema)) - if err != nil { - return err - } - defer schrows.Close() - - if !schrows.Next() { - // Create and setup a DB schema - _, err = db.Exec("CREATE SCHEMA " + setting.Database.Schema) - if err != nil { - return err - } - } - - // Make the user's default search path the created schema; this will affect new connections - _, err = db.Exec(fmt.Sprintf(`ALTER USER "%s" SET search_path = %s`, setting.Database.User, setting.Database.Schema)) - if err != nil { - return err - } - return nil - } - case setting.Database.Type.IsMSSQL(): - host, port := setting.ParseMSSQLHostPort(setting.Database.Host) - db, err := sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", - host, port, "master", setting.Database.User, setting.Database.Passwd)) - if err != nil { - return err - } - defer db.Close() - - if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS [%s]", setting.Database.Name)); err != nil { - return err - } - if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE [%s]", setting.Database.Name)); err != nil { - return err - } - } - - return nil -} diff --git a/models/migrations/base/db_test.go b/models/migrations/base/db_test.go index 80bf00b22a..00635ca72e 100644 --- a/models/migrations/base/db_test.go +++ b/models/migrations/base/db_test.go @@ -11,6 +11,10 @@ import ( "xorm.io/xorm/names" ) +func TestMain(m *testing.M) { + MainTest(m) +} + func Test_DropTableColumns(t *testing.T) { x, deferable := PrepareTestEnv(t, 0) if x == nil || t.Failed() { diff --git a/models/migrations/base/main_test.go b/models/migrations/base/main_test.go deleted file mode 100644 index c1c789150f..0000000000 --- a/models/migrations/base/main_test.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2021 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package base - -import ( - "testing" -) - -func TestMain(m *testing.M) { - MainTest(m) -} diff --git a/models/migrations/base/tests.go b/models/migrations/base/tests.go index 83beca8fb9..36afd35dd4 100644 --- a/models/migrations/base/tests.go +++ b/models/migrations/base/tests.go @@ -4,18 +4,21 @@ package base import ( + "database/sql" "fmt" "os" + "path" "path/filepath" - "runtime" "testing" + "time" + "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/tempdir" - "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/testlogger" + "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/require" "xorm.io/xorm" @@ -24,6 +27,117 @@ import ( // FIXME: this file shouldn't be in a normal package, it should only be compiled for tests +func removeAllWithRetry(dir string) error { + var err error + for range 20 { + err = os.RemoveAll(dir) + if err == nil { + break + } + time.Sleep(100 * time.Millisecond) + } + return err +} + +func newXORMEngine(t *testing.T) (*xorm.Engine, error) { + if err := db.InitEngine(t.Context()); err != nil { + return nil, err + } + x := unittest.GetXORMEngine() + return x, nil +} + +func deleteDB() error { + switch { + case setting.Database.Type.IsSQLite3(): + if err := util.Remove(setting.Database.Path); err != nil { + return err + } + return os.MkdirAll(path.Dir(setting.Database.Path), os.ModePerm) + + case setting.Database.Type.IsMySQL(): + db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/", + setting.Database.User, setting.Database.Passwd, setting.Database.Host)) + if err != nil { + return err + } + defer db.Close() + + if _, err = db.Exec("DROP DATABASE IF EXISTS " + setting.Database.Name); err != nil { + return err + } + + if _, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + setting.Database.Name); err != nil { + return err + } + return nil + case setting.Database.Type.IsPostgreSQL(): + db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/?sslmode=%s", + setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.SSLMode)) + if err != nil { + return err + } + defer db.Close() + + if _, err = db.Exec("DROP DATABASE IF EXISTS " + setting.Database.Name); err != nil { + return err + } + + if _, err = db.Exec("CREATE DATABASE " + setting.Database.Name); err != nil { + return err + } + db.Close() + + // Check if we need to setup a specific schema + if len(setting.Database.Schema) != 0 { + db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s", + setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode)) + if err != nil { + return err + } + defer db.Close() + + schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema)) + if err != nil { + return err + } + defer schrows.Close() + + if !schrows.Next() { + // Create and setup a DB schema + _, err = db.Exec("CREATE SCHEMA " + setting.Database.Schema) + if err != nil { + return err + } + } + + // Make the user's default search path the created schema; this will affect new connections + _, err = db.Exec(fmt.Sprintf(`ALTER USER "%s" SET search_path = %s`, setting.Database.User, setting.Database.Schema)) + if err != nil { + return err + } + return nil + } + case setting.Database.Type.IsMSSQL(): + host, port := setting.ParseMSSQLHostPort(setting.Database.Host) + db, err := sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", + host, port, "master", setting.Database.User, setting.Database.Passwd)) + if err != nil { + return err + } + defer db.Close() + + if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS [%s]", setting.Database.Name)); err != nil { + return err + } + if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE [%s]", setting.Database.Name)); err != nil { + return err + } + } + + return nil +} + // PrepareTestEnv prepares the test environment and reset the database. The skip parameter should usually be 0. // Provide models to be sync'd with the database - in particular any models you expect fixtures to be loaded from. // @@ -40,7 +154,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu return nil, deferFn } - x, err := newXORMEngine() + x, err := newXORMEngine(t) require.NoError(t, err) if x != nil { oldDefer := deferFn @@ -101,28 +215,7 @@ func LoadTableSchemasMap(t *testing.T, x *xorm.Engine) map[string]*schemas.Table func MainTest(m *testing.M) { testlogger.Init() - - giteaRoot := test.SetupGiteaRoot() - giteaBinary := "gitea" - if runtime.GOOS == "windows" { - giteaBinary += ".exe" - } - setting.AppPath = filepath.Join(giteaRoot, giteaBinary) - if _, err := os.Stat(setting.AppPath); err != nil { - testlogger.Fatalf("Could not find gitea binary at %s\n", setting.AppPath) - } - - giteaConf := os.Getenv("GITEA_CONF") - if giteaConf == "" { - giteaConf = filepath.Join(filepath.Dir(setting.AppPath), "tests/sqlite.ini") - _, _ = fmt.Fprintf(os.Stderr, "Environment variable $GITEA_CONF not set - defaulting to %s\n", giteaConf) - } - - if !filepath.IsAbs(giteaConf) { - setting.CustomConf = filepath.Join(giteaRoot, giteaConf) - } else { - setting.CustomConf = giteaConf - } + setting.SetupGiteaTestEnv() tmpDataPath, cleanup, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("data") if err != nil { @@ -130,7 +223,6 @@ func MainTest(m *testing.M) { } defer cleanup() - setting.CustomPath = filepath.Join(setting.AppWorkPath, "custom") setting.AppDataPath = tmpDataPath unittest.InitSettingsForTesting() diff --git a/models/unittest/fixtures_test.go b/models/unittest/fixtures_test.go index 8a4c5f1793..ebf209f5f4 100644 --- a/models/unittest/fixtures_test.go +++ b/models/unittest/fixtures_test.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/setting" "github.com/stretchr/testify/require" "xorm.io/xorm" @@ -60,7 +60,8 @@ func NewFixturesLoaderVendorGoTestfixtures(e *xorm.Engine, opts unittest.Fixture func prepareTestFixturesLoaders(t testing.TB) unittest.FixturesOptions { _ = user_model.User{} - opts := unittest.FixturesOptions{Dir: filepath.Join(test.SetupGiteaRoot(), "models", "fixtures"), Files: []string{ + giteaRoot := setting.SetupGiteaTestEnv() + opts := unittest.FixturesOptions{Dir: filepath.Join(giteaRoot, "models", "fixtures"), Files: []string{ "user.yml", }} require.NoError(t, unittest.CreateTestEngine(opts)) diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go index 4611a079ec..398090760e 100644 --- a/models/unittest/testdb.go +++ b/models/unittest/testdb.go @@ -21,7 +21,6 @@ import ( "code.gitea.io/gitea/modules/setting/config" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/tempdir" - "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" @@ -60,7 +59,6 @@ func InitSettingsForTesting() { _ = hash.Register("dummy", hash.NewDummyHasher) setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy") - setting.InitGiteaEnvVarsForTesting() } // TestOptions represents test options @@ -74,8 +72,7 @@ type TestOptions struct { // test database. Creates the test database, and sets necessary settings. func MainTest(m *testing.M, testOptsArg ...*TestOptions) { testOpts := util.OptionalArg(testOptsArg, &TestOptions{}) - giteaRoot = test.SetupGiteaRoot() - setting.CustomPath = filepath.Join(giteaRoot, "custom") + giteaRoot = setting.SetupGiteaTestEnv() InitSettingsForTesting() fixturesOpts := FixturesOptions{Dir: filepath.Join(giteaRoot, "models", "fixtures"), Files: testOpts.FixtureFiles} @@ -172,7 +169,7 @@ func CreateTestEngine(opts FixturesOptions) error { x, err := xorm.NewEngine("sqlite3", "file::memory:?cache=shared&_txlock=immediate") if err != nil { if strings.Contains(err.Error(), "unknown driver") { - return fmt.Errorf(`sqlite3 requires: -tags sqlite,sqlite_unlock_notify%s%w`, "\n", err) + return fmt.Errorf("sqlite3 requires: -tags sqlite,sqlite_unlock_notify\n%w", err) } return err } @@ -182,7 +179,7 @@ func CreateTestEngine(opts FixturesOptions) error { if err = db.SyncAllTables(); err != nil { return err } - switch os.Getenv("GITEA_UNIT_TESTS_LOG_SQL") { + switch os.Getenv("GITEA_TEST_LOG_SQL") { case "true", "1": x.ShowSQL(true) } @@ -201,5 +198,5 @@ func PrepareTestEnv(t testing.TB) { assert.NoError(t, PrepareTestDatabase()) metaPath := filepath.Join(giteaRoot, "tests", "gitea-repositories-meta") assert.NoError(t, SyncDirs(metaPath, setting.RepoRootPath)) - test.SetupGiteaRoot() // Makes sure GITEA_ROOT is set + setting.SetupGiteaTestEnv() } diff --git a/modules/gitrepo/main_test.go b/modules/gitrepo/main_test.go index d41a1a6ad4..e47eda7bc9 100644 --- a/modules/gitrepo/main_test.go +++ b/modules/gitrepo/main_test.go @@ -8,12 +8,12 @@ import ( "testing" "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/setting" ) func TestMain(m *testing.M) { // resolve repository path relative to the test directory - testRootDir := test.SetupGiteaRoot() + testRootDir := setting.SetupGiteaTestEnv() repoPath = func(repo Repository) string { if filepath.IsAbs(repo.RelativePath()) { return repo.RelativePath() // for testing purpose only diff --git a/modules/setting/config_env.go b/modules/setting/config_env.go index 4758eb72cb..e956e34439 100644 --- a/modules/setting/config_env.go +++ b/modules/setting/config_env.go @@ -167,24 +167,13 @@ func EnvironmentToConfig(cfg ConfigProvider, envs []string) (changed bool) { return changed } -// InitGiteaEnvVars initializes the environment variables for gitea -func InitGiteaEnvVars() { +func UnsetUnnecessaryEnvVars() { // Ideally Gitea should only accept the environment variables which it clearly knows instead of unsetting the ones it doesn't want, - // but the ideal behavior would be a breaking change, and it seems not bringing enough benefits to end users, - // so at the moment we could still keep "unsetting the unnecessary environments" + // but the ideal behavior would be a breaking change, and it seems not bringing enough benefits to end users. + // So at the moment we just keep "unsetting the unnecessary environment variables". // HOME is managed by Gitea, Gitea's git should use "HOME/.gitconfig". // But git would try "XDG_CONFIG_HOME/git/config" first if "HOME/.gitconfig" does not exist, // then our git.InitFull would still write to "XDG_CONFIG_HOME/git/config" if XDG_CONFIG_HOME is set. _ = os.Unsetenv("XDG_CONFIG_HOME") } - -func InitGiteaEnvVarsForTesting() { - InitGiteaEnvVars() - _ = os.Unsetenv("GIT_AUTHOR_NAME") - _ = os.Unsetenv("GIT_AUTHOR_EMAIL") - _ = os.Unsetenv("GIT_AUTHOR_DATE") - _ = os.Unsetenv("GIT_COMMITTER_NAME") - _ = os.Unsetenv("GIT_COMMITTER_EMAIL") - _ = os.Unsetenv("GIT_COMMITTER_DATE") -} diff --git a/modules/setting/testenv.go b/modules/setting/testenv.go new file mode 100644 index 0000000000..52e8912af0 --- /dev/null +++ b/modules/setting/testenv.go @@ -0,0 +1,61 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package setting + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + + "code.gitea.io/gitea/modules/util" +) + +func SetupGiteaTestEnv() string { + giteaRoot := os.Getenv("GITEA_TEST_ROOT") + if giteaRoot == "" { + _, filename, _, _ := runtime.Caller(0) + giteaRoot = filepath.Dir(filepath.Dir(filepath.Dir(filename))) + fixturesDir := filepath.Join(giteaRoot, "models", "fixtures") + if _, err := os.Stat(fixturesDir); err != nil { + panic("in gitea source code directory, fixtures directory not found: " + fixturesDir) + } + } + + appWorkPathBuiltin = giteaRoot + AppWorkPath = giteaRoot + AppPath = filepath.Join(giteaRoot, "gitea") + util.Iif(IsWindows, ".exe", "") + + // giteaConf (GITEA_CONF) must be relative because it is used in the git hooks as "$GITEA_ROOT/$GITEA_CONF" + giteaConf := os.Getenv("GITEA_TEST_CONF") + if giteaConf == "" { + // By default, use sqlite.ini for testing, then IDE like GoLand can start the test process with debugger. + // It's easier for developers to debug bugs step by step with a debugger. + // Notice: when doing "ssh push", Gitea executes sub processes, debugger won't work for the sub processes. + giteaConf = "tests/sqlite.ini" + _, _ = fmt.Fprintf(os.Stderr, "Environment variable GITEA_TEST_CONF not set - defaulting to %s\n", giteaConf) + if !EnableSQLite3 { + _, _ = fmt.Fprintf(os.Stderr, "sqlite3 requires: -tags sqlite,sqlite_unlock_notify\n") + os.Exit(1) + } + } + // CustomConf must be absolute path to make tests pass, + CustomConf = filepath.Join(AppWorkPath, giteaConf) + + // also unset unnecessary env vars for testing (only keep "GITEA_TEST_*" ones) + UnsetUnnecessaryEnvVars() + for _, env := range os.Environ() { + if strings.HasPrefix(env, "GIT_") || (strings.HasPrefix(env, "GITEA_") && !strings.HasPrefix(env, "GITEA_TEST_")) { + k, _, _ := strings.Cut(env, "=") + _ = os.Unsetenv(k) + } + } + + // TODO: some git repo hooks (test fixtures) still use these env variables, need to be refactored in the future + _ = os.Setenv("GITEA_ROOT", giteaRoot) + _ = os.Setenv("GITEA_CONF", giteaConf) // test fixture git hooks use "$GITEA_ROOT/$GITEA_CONF" in their scripts + + return giteaRoot +} diff --git a/modules/test/utils.go b/modules/test/utils.go index 34c11ff6b2..193fee28c8 100644 --- a/modules/test/utils.go +++ b/modules/test/utils.go @@ -9,13 +9,9 @@ import ( "io" "net/http" "net/http/httptest" - "os" - "path/filepath" - "runtime" "strings" "code.gitea.io/gitea/modules/json" - "code.gitea.io/gitea/modules/util" ) // RedirectURL returns the redirect URL of a http response. @@ -59,22 +55,6 @@ func MockVariableValue[T any](p *T, v ...T) (reset func()) { return func() { *p = old } } -// SetupGiteaRoot Sets GITEA_ROOT if it is not already set and returns the value -func SetupGiteaRoot() string { - giteaRoot := os.Getenv("GITEA_ROOT") - if giteaRoot != "" { - return giteaRoot - } - _, filename, _, _ := runtime.Caller(0) - giteaRoot = filepath.Dir(filepath.Dir(filepath.Dir(filename))) - fixturesDir := filepath.Join(giteaRoot, "models", "fixtures") - if exist, _ := util.IsDir(fixturesDir); !exist { - panic("fixtures directory not found: " + fixturesDir) - } - _ = os.Setenv("GITEA_ROOT", giteaRoot) - return giteaRoot -} - func ReadAllTarGzContent(r io.Reader) (map[string]string, error) { gzr, err := gzip.NewReader(r) if err != nil { diff --git a/modules/test/utils_test.go b/modules/test/utils_test.go deleted file mode 100644 index 0469ce97f2..0000000000 --- a/modules/test/utils_test.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2024 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package test - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSetupGiteaRoot(t *testing.T) { - t.Setenv("GITEA_ROOT", "test") - assert.Equal(t, "test", SetupGiteaRoot()) - t.Setenv("GITEA_ROOT", "") - assert.NotEqual(t, "test", SetupGiteaRoot()) -} diff --git a/modules/testlogger/testlogger.go b/modules/testlogger/testlogger.go index b0f38644a7..bf08e1d6d5 100644 --- a/modules/testlogger/testlogger.go +++ b/modules/testlogger/testlogger.go @@ -118,7 +118,7 @@ func PrintCurrentTest(t testing.TB, skip ...int) func() { deferHasRun := false t.Cleanup(func() { if !deferHasRun { - Printf("!!! defer function hasn't been run but Cleanup is called\n%s", getRuntimeStackAll()) + Printf("!!! %s defer function hasn't been run but Cleanup is called, usually caused by panic", t.Name()) } }) Printf("=== %s (%s:%d)\n", log.NewColoredValue(t.Name()), strings.TrimPrefix(filename, prefix), line) @@ -171,16 +171,6 @@ func Init() { prefix = strings.TrimSuffix(filename, relFilePath) log.RegisterEventWriter("test", newTestLoggerWriter) - - duration, err := time.ParseDuration(os.Getenv("GITEA_TEST_SLOW_RUN")) - if err == nil && duration > 0 { - TestSlowRun = duration - } - - duration, err = time.ParseDuration(os.Getenv("GITEA_TEST_SLOW_FLUSH")) - if err == nil && duration > 0 { - TestSlowFlush = duration - } } func Fatalf(format string, args ...any) { diff --git a/playwright.config.ts b/playwright.config.ts index d1cd299e25..9e3396465a 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -2,7 +2,7 @@ import {devices} from '@playwright/test'; import {env} from 'node:process'; import type {PlaywrightTestConfig} from '@playwright/test'; -const BASE_URL = env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localhost:3000'; +const BASE_URL = env.GITEA_TEST_SERVER_URL?.replace?.(/\/$/g, '') || 'http://localhost:3000'; export default { testDir: './tests/e2e/', diff --git a/routers/web/healthcheck/check.go b/routers/web/healthcheck/check.go index 85f47613f0..0eea1e1ff7 100644 --- a/routers/web/healthcheck/check.go +++ b/routers/web/healthcheck/check.go @@ -64,6 +64,15 @@ type componentStatus struct { } // Check is the health check API handler +// +// HINT: HEALTH-CHECK-ENDPOINT: there is no clear definition about what "health" means. +// In most cases, end users don't need to check such endpoint, because even if database is down, +// Gitea will reover after database is up again. Sysop should monitor database and cache status directly. +// +// And keep in mind: this health check should NEVER be used as a "restart" trigger, for example: Docker's "HEALTHCHECK". +// * If Gitea is upgrading and migrating database, there will be a long time before this endpoint starts to return "pass" status. +// In this case, if the checker restarts Gitea just because it doesn't get "pass" status in short time, +// the instance will just be restarted again and again before the migation finishes and the sitution just goes worse. func Check(w http.ResponseWriter, r *http.Request) { rsp := response{ Status: pass, diff --git a/services/migrations/gitea_downloader_test.go b/services/migrations/gitea_downloader_test.go index fb985ee9d5..1a9094f6f2 100644 --- a/services/migrations/gitea_downloader_test.go +++ b/services/migrations/gitea_downloader_test.go @@ -17,10 +17,10 @@ import ( ) func TestGiteaDownloadRepo(t *testing.T) { - // Skip tests if Gitea token is not found - giteaToken := os.Getenv("GITEA_TOKEN") + // Skip tests if Gitea token is not found (TODO: this test seems stopped for long time because there is no token in CI secrets) + giteaToken := os.Getenv("GITEA_TEST_OFFICIAL_SITE_TOKEN") if giteaToken == "" { - t.Skip("skipped test because GITEA_TOKEN was not in the environment") + t.Skip("skipped test because GITEA_TEST_OFFICIAL_SITE_TOKEN was not in the environment") } resp, err := http.Get("https://gitea.com/gitea") diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 4a408dbd7b..95093ffd29 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -94,7 +94,7 @@ func TestE2e(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { cmd := exec.Command(runArgs[0], runArgs...) cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "GITEA_URL="+setting.AppURL) + cmd.Env = append(cmd.Env, "GITEA_TEST_SERVER_URL="+setting.AppURL) var stdout, stderr bytes.Buffer cmd.Stdout = &stdout diff --git a/tests/integration/migration-test/migration_test.go b/tests/integration/migration-test/migration_test.go index 2659c5c53d..ee49829127 100644 --- a/tests/integration/migration-test/migration_test.go +++ b/tests/integration/migration-test/migration_test.go @@ -25,7 +25,6 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/testlogger" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" @@ -37,20 +36,7 @@ var currentEngine *xorm.Engine func initMigrationTest(t *testing.T) func() { testlogger.Init() - giteaRoot := test.SetupGiteaRoot() - setting.AppPath = filepath.Join(giteaRoot, "gitea") - if _, err := os.Stat(setting.AppPath); err != nil { - testlogger.Fatalf(fmt.Sprintf("Could not find gitea binary at %s\n", setting.AppPath)) - } - - giteaConf := os.Getenv("GITEA_CONF") - if giteaConf == "" { - testlogger.Fatalf("Environment variable $GITEA_CONF not set\n") - } else if !path.IsAbs(giteaConf) { - setting.CustomConf = filepath.Join(giteaRoot, giteaConf) - } else { - setting.CustomConf = giteaConf - } + setting.SetupGiteaTestEnv() unittest.InitSettingsForTesting() diff --git a/tests/test_utils.go b/tests/test_utils.go index e63eb75846..0cb99a1f2c 100644 --- a/tests/test_utils.go +++ b/tests/test_utils.go @@ -6,7 +6,6 @@ package tests import ( "database/sql" "fmt" - "os" "path/filepath" "testing" @@ -18,7 +17,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" - "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/testlogger" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers" @@ -29,40 +27,7 @@ import ( func InitTest(requireGitea bool) { testlogger.Init() - giteaRoot := test.SetupGiteaRoot() - - // TODO: Speedup tests that rely on the event source ticker, confirm whether there is any bug or failure. - // setting.UI.Notification.EventSourceUpdateTime = time.Second - - setting.AppWorkPath = giteaRoot - setting.CustomPath = filepath.Join(setting.AppWorkPath, "custom") - if requireGitea { - giteaBinary := "gitea" - if setting.IsWindows { - giteaBinary += ".exe" - } - setting.AppPath = filepath.Join(giteaRoot, giteaBinary) - if _, err := os.Stat(setting.AppPath); err != nil { - testlogger.Fatalf("Could not find gitea binary at %s\n", setting.AppPath) - } - } - giteaConf := os.Getenv("GITEA_CONF") - if giteaConf == "" { - // By default, use sqlite.ini for testing, then IDE like GoLand can start the test process with debugger. - // It's easier for developers to debug bugs step by step with a debugger. - // Notice: when doing "ssh push", Gitea executes sub processes, debugger won't work for the sub processes. - giteaConf = "tests/sqlite.ini" - _ = os.Setenv("GITEA_CONF", giteaConf) - _, _ = fmt.Fprintf(os.Stderr, "Environment variable $GITEA_CONF not set - defaulting to %s\n", giteaConf) - if !setting.EnableSQLite3 { - testlogger.Fatalf(`sqlite3 requires: -tags sqlite,sqlite_unlock_notify` + "\n") - } - } - if !filepath.IsAbs(giteaConf) { - setting.CustomConf = filepath.Join(giteaRoot, giteaConf) - } else { - setting.CustomConf = giteaConf - } + setting.SetupGiteaTestEnv() unittest.InitSettingsForTesting() setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"