You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

testdb.go 8.6KB

Refactor path & config system (#25330) # The problem There were many "path tricks": * By default, Gitea uses its program directory as its work path * Gitea tries to use the "work path" to guess its "custom path" and "custom conf (app.ini)" * Users might want to use other directories as work path * The non-default work path should be passed to Gitea by GITEA_WORK_DIR or "--work-path" * But some Gitea processes are started without these values * The "serv" process started by OpenSSH server * The CLI sub-commands started by site admin * The paths are guessed by SetCustomPathAndConf again and again * The default values of "work path / custom path / custom conf" can be changed when compiling # The solution * Use `InitWorkPathAndCommonConfig` to handle these path tricks, and use test code to cover its behaviors. * When Gitea's web server runs, write the WORK_PATH to "app.ini", this value must be the most correct one, because if this value is not right, users would find that the web UI doesn't work and then they should be able to fix it. * Then all other sub-commands can use the WORK_PATH in app.ini to initialize their paths. * By the way, when Gitea starts for git protocol, it shouldn't output any log, otherwise the git protocol gets broken and client blocks forever. The "work path" priority is: WORK_PATH in app.ini > cmd arg --work-path > env var GITEA_WORK_DIR > builtin default The "app.ini" searching order is: cmd arg --config > cmd arg "work path / custom path" > env var "work path / custom path" > builtin default ## ⚠️ BREAKING If your instance's "work path / custom path / custom conf" doesn't meet the requirements (eg: work path must be absolute), Gitea will report a fatal error and exit. You need to set these values according to the error log. ---- Close #24818 Close #24222 Close #21606 Close #21498 Close #25107 Close #24981 Maybe close #24503 Replace #23301 Replace #22754 And maybe more
11 months ago
Refactor path & config system (#25330) # The problem There were many "path tricks": * By default, Gitea uses its program directory as its work path * Gitea tries to use the "work path" to guess its "custom path" and "custom conf (app.ini)" * Users might want to use other directories as work path * The non-default work path should be passed to Gitea by GITEA_WORK_DIR or "--work-path" * But some Gitea processes are started without these values * The "serv" process started by OpenSSH server * The CLI sub-commands started by site admin * The paths are guessed by SetCustomPathAndConf again and again * The default values of "work path / custom path / custom conf" can be changed when compiling # The solution * Use `InitWorkPathAndCommonConfig` to handle these path tricks, and use test code to cover its behaviors. * When Gitea's web server runs, write the WORK_PATH to "app.ini", this value must be the most correct one, because if this value is not right, users would find that the web UI doesn't work and then they should be able to fix it. * Then all other sub-commands can use the WORK_PATH in app.ini to initialize their paths. * By the way, when Gitea starts for git protocol, it shouldn't output any log, otherwise the git protocol gets broken and client blocks forever. The "work path" priority is: WORK_PATH in app.ini > cmd arg --work-path > env var GITEA_WORK_DIR > builtin default The "app.ini" searching order is: cmd arg --config > cmd arg "work path / custom path" > env var "work path / custom path" > builtin default ## ⚠️ BREAKING If your instance's "work path / custom path / custom conf" doesn't meet the requirements (eg: work path must be absolute), Gitea will report a fatal error and exit. You need to set these values according to the error log. ---- Close #24818 Close #24222 Close #21606 Close #21498 Close #25107 Close #24981 Maybe close #24503 Replace #23301 Replace #22754 And maybe more
11 months ago
Refactor path & config system (#25330) # The problem There were many "path tricks": * By default, Gitea uses its program directory as its work path * Gitea tries to use the "work path" to guess its "custom path" and "custom conf (app.ini)" * Users might want to use other directories as work path * The non-default work path should be passed to Gitea by GITEA_WORK_DIR or "--work-path" * But some Gitea processes are started without these values * The "serv" process started by OpenSSH server * The CLI sub-commands started by site admin * The paths are guessed by SetCustomPathAndConf again and again * The default values of "work path / custom path / custom conf" can be changed when compiling # The solution * Use `InitWorkPathAndCommonConfig` to handle these path tricks, and use test code to cover its behaviors. * When Gitea's web server runs, write the WORK_PATH to "app.ini", this value must be the most correct one, because if this value is not right, users would find that the web UI doesn't work and then they should be able to fix it. * Then all other sub-commands can use the WORK_PATH in app.ini to initialize their paths. * By the way, when Gitea starts for git protocol, it shouldn't output any log, otherwise the git protocol gets broken and client blocks forever. The "work path" priority is: WORK_PATH in app.ini > cmd arg --work-path > env var GITEA_WORK_DIR > builtin default The "app.ini" searching order is: cmd arg --config > cmd arg "work path / custom path" > env var "work path / custom path" > builtin default ## ⚠️ BREAKING If your instance's "work path / custom path / custom conf" doesn't meet the requirements (eg: work path must be absolute), Gitea will report a fatal error and exit. You need to set these values according to the error log. ---- Close #24818 Close #24222 Close #21606 Close #21498 Close #25107 Close #24981 Maybe close #24503 Replace #23301 Replace #22754 And maybe more
11 months ago
Add Package Registry (#16510) * Added package store settings. * Added models. * Added generic package registry. * Added tests. * Added NuGet package registry. * Moved service index to api file. * Added NPM package registry. * Added Maven package registry. * Added PyPI package registry. * Summary is deprecated. * Changed npm name. * Sanitize project url. * Allow only scoped packages. * Added user interface. * Changed method name. * Added missing migration file. * Set page info. * Added documentation. * Added documentation links. * Fixed wrong error message. * Lint template files. * Fixed merge errors. * Fixed unit test storage path. * Switch to json module. * Added suggestions. * Added package webhook. * Add package api. * Fixed swagger file. * Fixed enum and comments. * Fixed NuGet pagination. * Print test names. * Added api tests. * Fixed access level. * Fix User unmarshal. * Added RubyGems package registry. * Fix lint. * Implemented io.Writer. * Added support for sha256/sha512 checksum files. * Improved maven-metadata.xml support. * Added support for symbol package uploads. * Added tests. * Added overview docs. * Added npm dependencies and keywords. * Added no-packages information. * Display file size. * Display asset count. * Fixed filter alignment. * Added package icons. * Formatted instructions. * Allow anonymous package downloads. * Fixed comments. * Fixed postgres test. * Moved file. * Moved models to models/packages. * Use correct error response format per client. * Use simpler search form. * Fixed IsProd. * Restructured data model. * Prevent empty filename. * Fix swagger. * Implemented user/org registry. * Implemented UI. * Use GetUserByIDCtx. * Use table for dependencies. * make svg * Added support for unscoped npm packages. * Add support for npm dist tags. * Added tests for npm tags. * Unlink packages if repository gets deleted. * Prevent user/org delete if a packages exist. * Use package unlink in repository service. * Added support for composer packages. * Restructured package docs. * Added missing tests. * Fixed generic content page. * Fixed docs. * Fixed swagger. * Added missing type. * Fixed ambiguous column. * Organize content store by sha256 hash. * Added admin package management. * Added support for sorting. * Add support for multiple identical versions/files. * Added missing repository unlink. * Added file properties. * make fmt * lint * Added Conan package registry. * Updated docs. * Unify package names. * Added swagger enum. * Use longer TEXT column type. * Removed version composite key. * Merged package and container registry. * Removed index. * Use dedicated package router. * Moved files to new location. * Updated docs. * Fixed JOIN order. * Fixed GROUP BY statement. * Fixed GROUP BY #2. * Added symbol server support. * Added more tests. * Set NOT NULL. * Added setting to disable package registries. * Moved auth into service. * refactor * Use ctx everywhere. * Added package cleanup task. * Changed packages path. * Added container registry. * Refactoring * Updated comparison. * Fix swagger. * Fixed table order. * Use token auth for npm routes. * Enabled ReverseProxy auth. * Added packages link for orgs. * Fixed anonymous org access. * Enable copy button for setup instructions. * Merge error * Added suggestions. * Fixed merge. * Handle "generic". * Added link for TODO. * Added suggestions. * Changed temporary buffer filename. * Added suggestions. * Apply suggestions from code review Co-authored-by: Thomas Boerger <thomas@webhippie.de> * Update docs/content/doc/packages/nuget.en-us.md Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Thomas Boerger <thomas@webhippie.de>
2 years ago
Implement actions (#21937) Close #13539. Co-authored by: @lunny @appleboy @fuxiaohei and others. Related projects: - https://gitea.com/gitea/actions-proto-def - https://gitea.com/gitea/actions-proto-go - https://gitea.com/gitea/act - https://gitea.com/gitea/act_runner ### Summary The target of this PR is to bring a basic implementation of "Actions", an internal CI/CD system of Gitea. That means even though it has been merged, the state of the feature is **EXPERIMENTAL**, and please note that: - It is disabled by default; - It shouldn't be used in a production environment currently; - It shouldn't be used in a public Gitea instance currently; - Breaking changes may be made before it's stable. **Please comment on #13539 if you have any different product design ideas**, all decisions reached there will be adopted here. But in this PR, we don't talk about **naming, feature-creep or alternatives**. ### ⚠️ Breaking `gitea-actions` will become a reserved user name. If a user with the name already exists in the database, it is recommended to rename it. ### Some important reviews - What is `DEFAULT_ACTIONS_URL` in `app.ini` for? - https://github.com/go-gitea/gitea/pull/21937#discussion_r1055954954 - Why the api for runners is not under the normal `/api/v1` prefix? - https://github.com/go-gitea/gitea/pull/21937#discussion_r1061173592 - Why DBFS? - https://github.com/go-gitea/gitea/pull/21937#discussion_r1061301178 - Why ignore events triggered by `gitea-actions` bot? - https://github.com/go-gitea/gitea/pull/21937#discussion_r1063254103 - Why there's no permission control for actions? - https://github.com/go-gitea/gitea/pull/21937#discussion_r1090229868 ### What it looks like <details> #### Manage runners <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205870657-c72f590e-2e08-4cd4-be7f-2e0abb299bbf.png"> #### List runs <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205872794-50fde990-2b45-48c1-a178-908e4ec5b627.png"> #### View logs <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205872501-9b7b9000-9542-4991-8f55-18ccdada77c3.png"> </details> ### How to try it <details> #### 1. Start Gitea Clone this branch and [install from source](https://docs.gitea.io/en-us/install-from-source). Add additional configurations in `app.ini` to enable Actions: ```ini [actions] ENABLED = true ``` Start it. If all is well, you'll see the management page of runners: <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205877365-8e30a780-9b10-4154-b3e8-ee6c3cb35a59.png"> #### 2. Start runner Clone the [act_runner](https://gitea.com/gitea/act_runner), and follow the [README](https://gitea.com/gitea/act_runner/src/branch/main/README.md) to start it. If all is well, you'll see a new runner has been added: <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205878000-216f5937-e696-470d-b66c-8473987d91c3.png"> #### 3. Enable actions for a repo Create a new repo or open an existing one, check the `Actions` checkbox in settings and submit. <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205879705-53e09208-73c0-4b3e-a123-2dcf9aba4b9c.png"> <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205879383-23f3d08f-1a85-41dd-a8b3-54e2ee6453e8.png"> If all is well, you'll see a new tab "Actions": <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205881648-a8072d8c-5803-4d76-b8a8-9b2fb49516c1.png"> #### 4. Upload workflow files Upload some workflow files to `.gitea/workflows/xxx.yaml`, you can follow the [quickstart](https://docs.github.com/en/actions/quickstart) of GitHub Actions. Yes, Gitea Actions is compatible with GitHub Actions in most cases, you can use the same demo: ```yaml name: GitHub Actions Demo run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 on: [push] jobs: Explore-GitHub-Actions: runs-on: ubuntu-latest steps: - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - name: Check out repository code uses: actions/checkout@v3 - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." - run: echo "🖥️ The workflow is now ready to test your code on the runner." - name: List files in the repository run: | ls ${{ github.workspace }} - run: echo "🍏 This job's status is ${{ job.status }}." ``` If all is well, you'll see a new run in `Actions` tab: <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205884473-79a874bc-171b-4aaf-acd5-0241a45c3b53.png"> #### 5. Check the logs of jobs Click a run and you'll see the logs: <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/205884800-994b0374-67f7-48ff-be9a-4c53f3141547.png"> #### 6. Go on You can try more examples in [the documents](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions) of GitHub Actions, then you might find a lot of bugs. Come on, PRs are welcome. </details> See also: [Feature Preview: Gitea Actions](https://blog.gitea.io/2022/12/feature-preview-gitea-actions/) --------- Co-authored-by: a1012112796 <1012112796@qq.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: delvh <dev.lh@web.de> Co-authored-by: ChristopherHX <christopher.homberger@web.de> Co-authored-by: John Olheiser <john.olheiser@gmail.com>
1 year ago
Rewrite queue (#24505) # ⚠️ Breaking Many deprecated queue config options are removed (actually, they should have been removed in 1.18/1.19). If you see the fatal message when starting Gitea: "Please update your app.ini to remove deprecated config options", please follow the error messages to remove these options from your app.ini. Example: ``` 2023/05/06 19:39:22 [E] Removed queue option: `[indexer].ISSUE_INDEXER_QUEUE_TYPE`. Use new options in `[queue.issue_indexer]` 2023/05/06 19:39:22 [E] Removed queue option: `[indexer].UPDATE_BUFFER_LEN`. Use new options in `[queue.issue_indexer]` 2023/05/06 19:39:22 [F] Please update your app.ini to remove deprecated config options ``` Many options in `[queue]` are are dropped, including: `WRAP_IF_NECESSARY`, `MAX_ATTEMPTS`, `TIMEOUT`, `WORKERS`, `BLOCK_TIMEOUT`, `BOOST_TIMEOUT`, `BOOST_WORKERS`, they can be removed from app.ini. # The problem The old queue package has some legacy problems: * complexity: I doubt few people could tell how it works. * maintainability: Too many channels and mutex/cond are mixed together, too many different structs/interfaces depends each other. * stability: due to the complexity & maintainability, sometimes there are strange bugs and difficult to debug, and some code doesn't have test (indeed some code is difficult to test because a lot of things are mixed together). * general applicability: although it is called "queue", its behavior is not a well-known queue. * scalability: it doesn't seem easy to make it work with a cluster without breaking its behaviors. It came from some very old code to "avoid breaking", however, its technical debt is too heavy now. It's a good time to introduce a better "queue" package. # The new queue package It keeps using old config and concept as much as possible. * It only contains two major kinds of concepts: * The "base queue": channel, levelqueue, redis * They have the same abstraction, the same interface, and they are tested by the same testing code. * The "WokerPoolQueue", it uses the "base queue" to provide "worker pool" function, calls the "handler" to process the data in the base queue. * The new code doesn't do "PushBack" * Think about a queue with many workers, the "PushBack" can't guarantee the order for re-queued unhandled items, so in new code it just does "normal push" * The new code doesn't do "pause/resume" * The "pause/resume" was designed to handle some handler's failure: eg: document indexer (elasticsearch) is down * If a queue is paused for long time, either the producers blocks or the new items are dropped. * The new code doesn't do such "pause/resume" trick, it's not a common queue's behavior and it doesn't help much. * If there are unhandled items, the "push" function just blocks for a few seconds and then re-queue them and retry. * The new code doesn't do "worker booster" * Gitea's queue's handlers are light functions, the cost is only the go-routine, so it doesn't make sense to "boost" them. * The new code only use "max worker number" to limit the concurrent workers. * The new "Push" never blocks forever * Instead of creating more and more blocking goroutines, return an error is more friendly to the server and to the end user. There are more details in code comments: eg: the "Flush" problem, the strange "code.index" hanging problem, the "immediate" queue problem. Almost ready for review. TODO: * [x] add some necessary comments during review * [x] add some more tests if necessary * [x] update documents and config options * [x] test max worker / active worker * [x] re-run the CI tasks to see whether any test is flaky * [x] improve the `handleOldLengthConfiguration` to provide more friendly messages * [x] fine tune default config values (eg: length?) ## Code coverage: ![image](https://user-images.githubusercontent.com/2114189/236620635-55576955-f95d-4810-b12f-879026a3afdf.png)
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package unittest
  4. import (
  5. "context"
  6. "fmt"
  7. "log"
  8. "os"
  9. "path/filepath"
  10. "strings"
  11. "testing"
  12. "code.gitea.io/gitea/models/db"
  13. "code.gitea.io/gitea/models/system"
  14. "code.gitea.io/gitea/modules/auth/password/hash"
  15. "code.gitea.io/gitea/modules/base"
  16. "code.gitea.io/gitea/modules/cache"
  17. "code.gitea.io/gitea/modules/git"
  18. "code.gitea.io/gitea/modules/setting"
  19. "code.gitea.io/gitea/modules/setting/config"
  20. "code.gitea.io/gitea/modules/storage"
  21. "code.gitea.io/gitea/modules/util"
  22. "github.com/stretchr/testify/assert"
  23. "xorm.io/xorm"
  24. "xorm.io/xorm/names"
  25. )
  26. // giteaRoot a path to the gitea root
  27. var (
  28. giteaRoot string
  29. fixturesDir string
  30. )
  31. // FixturesDir returns the fixture directory
  32. func FixturesDir() string {
  33. return fixturesDir
  34. }
  35. func fatalTestError(fmtStr string, args ...any) {
  36. _, _ = fmt.Fprintf(os.Stderr, fmtStr, args...)
  37. os.Exit(1)
  38. }
  39. // InitSettings initializes config provider and load common settings for tests
  40. func InitSettings() {
  41. if setting.CustomConf == "" {
  42. setting.CustomConf = filepath.Join(setting.CustomPath, "conf/app-unittest-tmp.ini")
  43. _ = os.Remove(setting.CustomConf)
  44. }
  45. setting.InitCfgProvider(setting.CustomConf)
  46. setting.LoadCommonSettings()
  47. if err := setting.PrepareAppDataPath(); err != nil {
  48. log.Fatalf("Can not prepare APP_DATA_PATH: %v", err)
  49. }
  50. // register the dummy hash algorithm function used in the test fixtures
  51. _ = hash.Register("dummy", hash.NewDummyHasher)
  52. setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
  53. }
  54. // TestOptions represents test options
  55. type TestOptions struct {
  56. FixtureFiles []string
  57. SetUp func() error // SetUp will be executed before all tests in this package
  58. TearDown func() error // TearDown will be executed after all tests in this package
  59. }
  60. // MainTest a reusable TestMain(..) function for unit tests that need to use a
  61. // test database. Creates the test database, and sets necessary settings.
  62. func MainTest(m *testing.M, testOpts ...*TestOptions) {
  63. searchDir, _ := os.Getwd()
  64. for searchDir != "" {
  65. if _, err := os.Stat(filepath.Join(searchDir, "go.mod")); err == nil {
  66. break // The "go.mod" should be the one for Gitea repository
  67. }
  68. if dir := filepath.Dir(searchDir); dir == searchDir {
  69. searchDir = "" // reaches the root of filesystem
  70. } else {
  71. searchDir = dir
  72. }
  73. }
  74. if searchDir == "" {
  75. panic("The tests should run in a Gitea repository, there should be a 'go.mod' in the root")
  76. }
  77. giteaRoot = searchDir
  78. setting.CustomPath = filepath.Join(giteaRoot, "custom")
  79. InitSettings()
  80. fixturesDir = filepath.Join(giteaRoot, "models", "fixtures")
  81. var opts FixturesOptions
  82. if len(testOpts) == 0 || len(testOpts[0].FixtureFiles) == 0 {
  83. opts.Dir = fixturesDir
  84. } else {
  85. for _, f := range testOpts[0].FixtureFiles {
  86. if len(f) != 0 {
  87. opts.Files = append(opts.Files, filepath.Join(fixturesDir, f))
  88. }
  89. }
  90. }
  91. if err := CreateTestEngine(opts); err != nil {
  92. fatalTestError("Error creating test engine: %v\n", err)
  93. }
  94. setting.IsInTesting = true
  95. setting.AppURL = "https://try.gitea.io/"
  96. setting.RunUser = "runuser"
  97. setting.SSH.User = "sshuser"
  98. setting.SSH.BuiltinServerUser = "builtinuser"
  99. setting.SSH.Port = 3000
  100. setting.SSH.Domain = "try.gitea.io"
  101. setting.Database.Type = "sqlite3"
  102. setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
  103. repoRootPath, err := os.MkdirTemp(os.TempDir(), "repos")
  104. if err != nil {
  105. fatalTestError("TempDir: %v\n", err)
  106. }
  107. setting.RepoRootPath = repoRootPath
  108. appDataPath, err := os.MkdirTemp(os.TempDir(), "appdata")
  109. if err != nil {
  110. fatalTestError("TempDir: %v\n", err)
  111. }
  112. setting.AppDataPath = appDataPath
  113. setting.AppWorkPath = giteaRoot
  114. setting.StaticRootPath = giteaRoot
  115. setting.GravatarSource = "https://secure.gravatar.com/avatar/"
  116. setting.Attachment.Storage.Path = filepath.Join(setting.AppDataPath, "attachments")
  117. setting.LFS.Storage.Path = filepath.Join(setting.AppDataPath, "lfs")
  118. setting.Avatar.Storage.Path = filepath.Join(setting.AppDataPath, "avatars")
  119. setting.RepoAvatar.Storage.Path = filepath.Join(setting.AppDataPath, "repo-avatars")
  120. setting.RepoArchive.Storage.Path = filepath.Join(setting.AppDataPath, "repo-archive")
  121. setting.Packages.Storage.Path = filepath.Join(setting.AppDataPath, "packages")
  122. setting.Actions.LogStorage.Path = filepath.Join(setting.AppDataPath, "actions_log")
  123. setting.Git.HomePath = filepath.Join(setting.AppDataPath, "home")
  124. setting.IncomingEmail.ReplyToAddress = "incoming+%{token}@localhost"
  125. config.SetDynGetter(system.NewDatabaseDynKeyGetter())
  126. if err = cache.Init(); err != nil {
  127. fatalTestError("cache.Init: %v\n", err)
  128. }
  129. if err = storage.Init(); err != nil {
  130. fatalTestError("storage.Init: %v\n", err)
  131. }
  132. if err = util.RemoveAll(repoRootPath); err != nil {
  133. fatalTestError("util.RemoveAll: %v\n", err)
  134. }
  135. if err = CopyDir(filepath.Join(giteaRoot, "tests", "gitea-repositories-meta"), setting.RepoRootPath); err != nil {
  136. fatalTestError("util.CopyDir: %v\n", err)
  137. }
  138. if err = git.InitFull(context.Background()); err != nil {
  139. fatalTestError("git.Init: %v\n", err)
  140. }
  141. ownerDirs, err := os.ReadDir(setting.RepoRootPath)
  142. if err != nil {
  143. fatalTestError("unable to read the new repo root: %v\n", err)
  144. }
  145. for _, ownerDir := range ownerDirs {
  146. if !ownerDir.Type().IsDir() {
  147. continue
  148. }
  149. repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name()))
  150. if err != nil {
  151. fatalTestError("unable to read the new repo root: %v\n", err)
  152. }
  153. for _, repoDir := range repoDirs {
  154. _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755)
  155. _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0o755)
  156. _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0o755)
  157. _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0o755)
  158. }
  159. }
  160. if len(testOpts) > 0 && testOpts[0].SetUp != nil {
  161. if err := testOpts[0].SetUp(); err != nil {
  162. fatalTestError("set up failed: %v\n", err)
  163. }
  164. }
  165. exitStatus := m.Run()
  166. if len(testOpts) > 0 && testOpts[0].TearDown != nil {
  167. if err := testOpts[0].TearDown(); err != nil {
  168. fatalTestError("tear down failed: %v\n", err)
  169. }
  170. }
  171. if err = util.RemoveAll(repoRootPath); err != nil {
  172. fatalTestError("util.RemoveAll: %v\n", err)
  173. }
  174. if err = util.RemoveAll(appDataPath); err != nil {
  175. fatalTestError("util.RemoveAll: %v\n", err)
  176. }
  177. os.Exit(exitStatus)
  178. }
  179. // FixturesOptions fixtures needs to be loaded options
  180. type FixturesOptions struct {
  181. Dir string
  182. Files []string
  183. }
  184. // CreateTestEngine creates a memory database and loads the fixture data from fixturesDir
  185. func CreateTestEngine(opts FixturesOptions) error {
  186. x, err := xorm.NewEngine("sqlite3", "file::memory:?cache=shared&_txlock=immediate")
  187. if err != nil {
  188. if strings.Contains(err.Error(), "unknown driver") {
  189. return fmt.Errorf(`sqlite3 requires: import _ "github.com/mattn/go-sqlite3" or -tags sqlite,sqlite_unlock_notify%s%w`, "\n", err)
  190. }
  191. return err
  192. }
  193. x.SetMapper(names.GonicMapper{})
  194. db.SetDefaultEngine(context.Background(), x)
  195. if err = db.SyncAllTables(); err != nil {
  196. return err
  197. }
  198. switch os.Getenv("GITEA_UNIT_TESTS_LOG_SQL") {
  199. case "true", "1":
  200. x.ShowSQL(true)
  201. }
  202. return InitFixtures(opts)
  203. }
  204. // PrepareTestDatabase load test fixtures into test database
  205. func PrepareTestDatabase() error {
  206. return LoadFixtures()
  207. }
  208. // PrepareTestEnv prepares the environment for unit tests. Can only be called
  209. // by tests that use the above MainTest(..) function.
  210. func PrepareTestEnv(t testing.TB) {
  211. assert.NoError(t, PrepareTestDatabase())
  212. assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
  213. metaPath := filepath.Join(giteaRoot, "tests", "gitea-repositories-meta")
  214. assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath))
  215. ownerDirs, err := os.ReadDir(setting.RepoRootPath)
  216. assert.NoError(t, err)
  217. for _, ownerDir := range ownerDirs {
  218. if !ownerDir.Type().IsDir() {
  219. continue
  220. }
  221. repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name()))
  222. assert.NoError(t, err)
  223. for _, repoDir := range repoDirs {
  224. _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755)
  225. _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0o755)
  226. _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0o755)
  227. _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0o755)
  228. }
  229. }
  230. base.SetupGiteaRoot() // Makes sure GITEA_ROOT is set
  231. }