gitea源码

test_utils.go 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package tests
  4. import (
  5. "database/sql"
  6. "fmt"
  7. "os"
  8. "path/filepath"
  9. "testing"
  10. "code.gitea.io/gitea/models/db"
  11. packages_model "code.gitea.io/gitea/models/packages"
  12. "code.gitea.io/gitea/models/unittest"
  13. "code.gitea.io/gitea/modules/git"
  14. "code.gitea.io/gitea/modules/graceful"
  15. "code.gitea.io/gitea/modules/log"
  16. "code.gitea.io/gitea/modules/setting"
  17. "code.gitea.io/gitea/modules/storage"
  18. "code.gitea.io/gitea/modules/test"
  19. "code.gitea.io/gitea/modules/testlogger"
  20. "code.gitea.io/gitea/modules/util"
  21. "code.gitea.io/gitea/routers"
  22. "github.com/stretchr/testify/assert"
  23. )
  24. func InitTest(requireGitea bool) {
  25. testlogger.Init()
  26. giteaRoot := test.SetupGiteaRoot()
  27. // TODO: Speedup tests that rely on the event source ticker, confirm whether there is any bug or failure.
  28. // setting.UI.Notification.EventSourceUpdateTime = time.Second
  29. setting.AppWorkPath = giteaRoot
  30. setting.CustomPath = filepath.Join(setting.AppWorkPath, "custom")
  31. if requireGitea {
  32. giteaBinary := "gitea"
  33. if setting.IsWindows {
  34. giteaBinary += ".exe"
  35. }
  36. setting.AppPath = filepath.Join(giteaRoot, giteaBinary)
  37. if _, err := os.Stat(setting.AppPath); err != nil {
  38. testlogger.Fatalf("Could not find gitea binary at %s\n", setting.AppPath)
  39. }
  40. }
  41. giteaConf := os.Getenv("GITEA_CONF")
  42. if giteaConf == "" {
  43. // By default, use sqlite.ini for testing, then IDE like GoLand can start the test process with debugger.
  44. // It's easier for developers to debug bugs step by step with a debugger.
  45. // Notice: when doing "ssh push", Gitea executes sub processes, debugger won't work for the sub processes.
  46. giteaConf = "tests/sqlite.ini"
  47. _ = os.Setenv("GITEA_CONF", giteaConf)
  48. _, _ = fmt.Fprintf(os.Stderr, "Environment variable $GITEA_CONF not set - defaulting to %s\n", giteaConf)
  49. if !setting.EnableSQLite3 {
  50. testlogger.Fatalf(`sqlite3 requires: -tags sqlite,sqlite_unlock_notify` + "\n")
  51. }
  52. }
  53. if !filepath.IsAbs(giteaConf) {
  54. setting.CustomConf = filepath.Join(giteaRoot, giteaConf)
  55. } else {
  56. setting.CustomConf = giteaConf
  57. }
  58. unittest.InitSettingsForTesting()
  59. setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
  60. if err := git.InitFull(); err != nil {
  61. log.Fatal("git.InitOnceWithSync: %v", err)
  62. }
  63. setting.LoadDBSetting()
  64. if err := storage.Init(); err != nil {
  65. testlogger.Fatalf("Init storage failed: %v\n", err)
  66. }
  67. switch {
  68. case setting.Database.Type.IsMySQL():
  69. connType := "tcp"
  70. if len(setting.Database.Host) > 0 && setting.Database.Host[0] == '/' { // looks like a unix socket
  71. connType = "unix"
  72. }
  73. db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@%s(%s)/",
  74. setting.Database.User, setting.Database.Passwd, connType, setting.Database.Host))
  75. defer db.Close()
  76. if err != nil {
  77. log.Fatal("sql.Open: %v", err)
  78. }
  79. if _, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + setting.Database.Name); err != nil {
  80. log.Fatal("db.Exec: %v", err)
  81. }
  82. case setting.Database.Type.IsPostgreSQL():
  83. var db *sql.DB
  84. var err error
  85. if setting.Database.Host[0] == '/' {
  86. db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@/%s?sslmode=%s&host=%s",
  87. setting.Database.User, setting.Database.Passwd, setting.Database.Name, setting.Database.SSLMode, setting.Database.Host))
  88. } else {
  89. db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
  90. setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode))
  91. }
  92. defer db.Close()
  93. if err != nil {
  94. log.Fatal("sql.Open: %v", err)
  95. }
  96. dbrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM pg_database WHERE datname = '%s'", setting.Database.Name))
  97. if err != nil {
  98. log.Fatal("db.Query: %v", err)
  99. }
  100. defer dbrows.Close()
  101. if !dbrows.Next() {
  102. if _, err = db.Exec("CREATE DATABASE " + setting.Database.Name); err != nil {
  103. log.Fatal("db.Exec: CREATE DATABASE: %v", err)
  104. }
  105. }
  106. // Check if we need to setup a specific schema
  107. if len(setting.Database.Schema) == 0 {
  108. break
  109. }
  110. db.Close()
  111. if setting.Database.Host[0] == '/' {
  112. db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@/%s?sslmode=%s&host=%s",
  113. setting.Database.User, setting.Database.Passwd, setting.Database.Name, setting.Database.SSLMode, setting.Database.Host))
  114. } else {
  115. db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
  116. setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode))
  117. }
  118. // This is a different db object; requires a different Close()
  119. defer db.Close()
  120. if err != nil {
  121. log.Fatal("sql.Open: %v", err)
  122. }
  123. schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema))
  124. if err != nil {
  125. log.Fatal("db.Query: %v", err)
  126. }
  127. defer schrows.Close()
  128. if !schrows.Next() {
  129. // Create and setup a DB schema
  130. if _, err = db.Exec("CREATE SCHEMA " + setting.Database.Schema); err != nil {
  131. log.Fatal("db.Exec: CREATE SCHEMA: %v", err)
  132. }
  133. }
  134. case setting.Database.Type.IsMSSQL():
  135. host, port := setting.ParseMSSQLHostPort(setting.Database.Host)
  136. db, err := sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;",
  137. host, port, "master", setting.Database.User, setting.Database.Passwd))
  138. if err != nil {
  139. log.Fatal("sql.Open: %v", err)
  140. }
  141. if _, err := db.Exec(fmt.Sprintf("If(db_id(N'%s') IS NULL) BEGIN CREATE DATABASE %s; END;", setting.Database.Name, setting.Database.Name)); err != nil {
  142. log.Fatal("db.Exec: %v", err)
  143. }
  144. defer db.Close()
  145. }
  146. routers.InitWebInstalled(graceful.GetManager().HammerContext())
  147. }
  148. func PrepareAttachmentsStorage(t testing.TB) {
  149. // prepare attachments directory and files
  150. assert.NoError(t, storage.Clean(storage.Attachments))
  151. s, err := storage.NewStorage(setting.LocalStorageType, &setting.Storage{
  152. Path: filepath.Join(filepath.Dir(setting.AppPath), "tests", "testdata", "data", "attachments"),
  153. })
  154. assert.NoError(t, err)
  155. assert.NoError(t, s.IterateObjects("", func(p string, obj storage.Object) error {
  156. _, err = storage.Copy(storage.Attachments, p, s, p)
  157. return err
  158. }))
  159. }
  160. func PrepareGitRepoDirectory(t testing.TB) {
  161. if !assert.NotEmpty(t, setting.RepoRootPath) {
  162. return
  163. }
  164. assert.NoError(t, unittest.SyncDirs(filepath.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath))
  165. }
  166. func PrepareArtifactsStorage(t testing.TB) {
  167. // prepare actions artifacts directory and files
  168. assert.NoError(t, storage.Clean(storage.ActionsArtifacts))
  169. s, err := storage.NewStorage(setting.LocalStorageType, &setting.Storage{
  170. Path: filepath.Join(filepath.Dir(setting.AppPath), "tests", "testdata", "data", "artifacts"),
  171. })
  172. assert.NoError(t, err)
  173. assert.NoError(t, s.IterateObjects("", func(p string, obj storage.Object) error {
  174. _, err = storage.Copy(storage.ActionsArtifacts, p, s, p)
  175. return err
  176. }))
  177. }
  178. func PrepareLFSStorage(t testing.TB) {
  179. // load LFS object fixtures
  180. // (LFS storage can be on any of several backends, including remote servers, so init it with the storage API)
  181. lfsFixtures, err := storage.NewStorage(setting.LocalStorageType, &setting.Storage{
  182. Path: filepath.Join(filepath.Dir(setting.AppPath), "tests/gitea-lfs-meta"),
  183. })
  184. assert.NoError(t, err)
  185. assert.NoError(t, storage.Clean(storage.LFS))
  186. assert.NoError(t, lfsFixtures.IterateObjects("", func(path string, _ storage.Object) error {
  187. _, err := storage.Copy(storage.LFS, path, lfsFixtures, path)
  188. return err
  189. }))
  190. }
  191. func PrepareCleanPackageData(t testing.TB) {
  192. // clear all package data
  193. assert.NoError(t, db.TruncateBeans(t.Context(),
  194. &packages_model.Package{},
  195. &packages_model.PackageVersion{},
  196. &packages_model.PackageFile{},
  197. &packages_model.PackageBlob{},
  198. &packages_model.PackageProperty{},
  199. &packages_model.PackageBlobUpload{},
  200. &packages_model.PackageCleanupRule{},
  201. ))
  202. assert.NoError(t, storage.Clean(storage.Packages))
  203. }
  204. func PrepareTestEnv(t testing.TB, skip ...int) func() {
  205. t.Helper()
  206. deferFn := PrintCurrentTest(t, util.OptionalArg(skip)+1)
  207. // load database fixtures
  208. assert.NoError(t, unittest.LoadFixtures())
  209. // do not add more Prepare* functions here, only call necessary ones in the related test functions
  210. PrepareGitRepoDirectory(t)
  211. PrepareLFSStorage(t)
  212. PrepareCleanPackageData(t)
  213. return deferFn
  214. }
  215. func PrintCurrentTest(t testing.TB, skip ...int) func() {
  216. t.Helper()
  217. return testlogger.PrintCurrentTest(t, util.OptionalArg(skip)+1)
  218. }