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.

dump_restore_test.go 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "context"
  7. "net/url"
  8. "os"
  9. "path/filepath"
  10. "strings"
  11. "testing"
  12. repo_model "code.gitea.io/gitea/models/repo"
  13. "code.gitea.io/gitea/models/unittest"
  14. user_model "code.gitea.io/gitea/models/user"
  15. base "code.gitea.io/gitea/modules/migration"
  16. "code.gitea.io/gitea/modules/setting"
  17. "code.gitea.io/gitea/modules/structs"
  18. "code.gitea.io/gitea/modules/util"
  19. "code.gitea.io/gitea/services/migrations"
  20. "github.com/stretchr/testify/assert"
  21. "gopkg.in/yaml.v2"
  22. )
  23. func TestDumpRestore(t *testing.T) {
  24. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  25. AllowLocalNetworks := setting.Migrations.AllowLocalNetworks
  26. setting.Migrations.AllowLocalNetworks = true
  27. AppVer := setting.AppVer
  28. // Gitea SDK (go-sdk) need to parse the AppVer from server response, so we must set it to a valid version string.
  29. setting.AppVer = "1.16.0"
  30. defer func() {
  31. setting.Migrations.AllowLocalNetworks = AllowLocalNetworks
  32. setting.AppVer = AppVer
  33. }()
  34. assert.NoError(t, migrations.Init())
  35. reponame := "repo1"
  36. basePath, err := os.MkdirTemp("", reponame)
  37. assert.NoError(t, err)
  38. defer util.RemoveAll(basePath)
  39. repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository)
  40. repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
  41. session := loginUser(t, repoOwner.Name)
  42. token := getTokenForLoggedInUser(t, session)
  43. //
  44. // Phase 1: dump repo1 from the Gitea instance to the filesystem
  45. //
  46. ctx := context.Background()
  47. opts := migrations.MigrateOptions{
  48. GitServiceType: structs.GiteaService,
  49. Issues: true,
  50. Labels: true,
  51. Milestones: true,
  52. Comments: true,
  53. AuthToken: token,
  54. CloneAddr: repo.CloneLink().HTTPS,
  55. RepoName: reponame,
  56. }
  57. err = migrations.DumpRepository(ctx, basePath, repoOwner.Name, opts)
  58. assert.NoError(t, err)
  59. //
  60. // Verify desired side effects of the dump
  61. //
  62. d := filepath.Join(basePath, repo.OwnerName, repo.Name)
  63. for _, f := range []string{"repo.yml", "topic.yml", "label.yml", "milestone.yml", "issue.yml"} {
  64. assert.FileExists(t, filepath.Join(d, f))
  65. }
  66. //
  67. // Phase 2: restore from the filesystem to the Gitea instance in restoredrepo
  68. //
  69. newreponame := "restoredrepo"
  70. err = migrations.RestoreRepository(ctx, d, repo.OwnerName, newreponame, []string{"labels", "milestones", "issues", "comments"}, false)
  71. assert.NoError(t, err)
  72. newrepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: newreponame}).(*repo_model.Repository)
  73. //
  74. // Phase 3: dump restoredrepo from the Gitea instance to the filesystem
  75. //
  76. opts.RepoName = newreponame
  77. opts.CloneAddr = newrepo.CloneLink().HTTPS
  78. err = migrations.DumpRepository(ctx, basePath, repoOwner.Name, opts)
  79. assert.NoError(t, err)
  80. //
  81. // Verify the dump of restoredrepo is the same as the dump of repo1
  82. //
  83. newd := filepath.Join(basePath, newrepo.OwnerName, newrepo.Name)
  84. for _, filename := range []string{"repo.yml", "label.yml", "milestone.yml"} {
  85. beforeBytes, err := os.ReadFile(filepath.Join(d, filename))
  86. assert.NoError(t, err)
  87. before := strings.ReplaceAll(string(beforeBytes), reponame, newreponame)
  88. after, err := os.ReadFile(filepath.Join(newd, filename))
  89. assert.NoError(t, err)
  90. assert.EqualValues(t, before, string(after))
  91. }
  92. beforeBytes, err := os.ReadFile(filepath.Join(d, "issue.yml"))
  93. assert.NoError(t, err)
  94. before := make([]*base.Issue, 0, 10)
  95. assert.NoError(t, yaml.Unmarshal(beforeBytes, &before))
  96. afterBytes, err := os.ReadFile(filepath.Join(newd, "issue.yml"))
  97. assert.NoError(t, err)
  98. after := make([]*base.Issue, 0, 10)
  99. assert.NoError(t, yaml.Unmarshal(afterBytes, &after))
  100. assert.EqualValues(t, len(before), len(after))
  101. if len(before) == len(after) {
  102. for i := 0; i < len(before); i++ {
  103. assert.EqualValues(t, before[i].Number, after[i].Number)
  104. assert.EqualValues(t, before[i].Title, after[i].Title)
  105. assert.EqualValues(t, before[i].Content, after[i].Content)
  106. assert.EqualValues(t, before[i].Ref, after[i].Ref)
  107. assert.EqualValues(t, before[i].Milestone, after[i].Milestone)
  108. assert.EqualValues(t, before[i].State, after[i].State)
  109. assert.EqualValues(t, before[i].IsLocked, after[i].IsLocked)
  110. assert.EqualValues(t, before[i].Created, after[i].Created)
  111. assert.EqualValues(t, before[i].Updated, after[i].Updated)
  112. assert.EqualValues(t, before[i].Labels, after[i].Labels)
  113. }
  114. }
  115. })
  116. }