backup_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright 2020 The Gogs 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 database
  5. import (
  6. "bytes"
  7. "context"
  8. "os"
  9. "path/filepath"
  10. "testing"
  11. "time"
  12. "github.com/pkg/errors"
  13. "github.com/stretchr/testify/require"
  14. "gorm.io/gorm"
  15. "gogs.io/gogs/internal/auth"
  16. "gogs.io/gogs/internal/auth/github"
  17. "gogs.io/gogs/internal/auth/pam"
  18. "gogs.io/gogs/internal/cryptoutil"
  19. "gogs.io/gogs/internal/dbtest"
  20. "gogs.io/gogs/internal/lfsutil"
  21. "gogs.io/gogs/internal/testutil"
  22. )
  23. func TestDumpAndImport(t *testing.T) {
  24. if testing.Short() {
  25. t.Skip()
  26. }
  27. t.Parallel()
  28. const wantTables = 8
  29. if len(Tables) != wantTables {
  30. t.Fatalf("New table has added (want %d got %d), please add new tests for the table and update this check", wantTables, len(Tables))
  31. }
  32. db := dbtest.NewDB(t, "dumpAndImport", Tables...)
  33. setupDBToDump(t, db)
  34. dumpTables(t, db)
  35. importTables(t, db)
  36. // Dump and assert golden again to make sure data aren't changed.
  37. dumpTables(t, db)
  38. }
  39. func setupDBToDump(t *testing.T, db *gorm.DB) {
  40. vals := []any{
  41. &Access{
  42. ID: 1,
  43. UserID: 1,
  44. RepoID: 11,
  45. Mode: AccessModeRead,
  46. },
  47. &Access{
  48. ID: 2,
  49. UserID: 2,
  50. RepoID: 22,
  51. Mode: AccessModeWrite,
  52. },
  53. &AccessToken{
  54. UserID: 1,
  55. Name: "test1",
  56. Sha1: cryptoutil.SHA1("2910d03d-c0b5-4f71-bad5-c4086e4efae3"),
  57. SHA256: cryptoutil.SHA256(cryptoutil.SHA1("2910d03d-c0b5-4f71-bad5-c4086e4efae3")),
  58. CreatedUnix: 1588568886,
  59. UpdatedUnix: 1588572486, // 1 hour later
  60. },
  61. &AccessToken{
  62. UserID: 1,
  63. Name: "test2",
  64. Sha1: cryptoutil.SHA1("84117e17-7e67-4024-bd04-1c23e6e809d4"),
  65. SHA256: cryptoutil.SHA256(cryptoutil.SHA1("84117e17-7e67-4024-bd04-1c23e6e809d4")),
  66. CreatedUnix: 1588568886,
  67. },
  68. &AccessToken{
  69. UserID: 2,
  70. Name: "test1",
  71. Sha1: cryptoutil.SHA1("da2775ce-73dd-47ba-b9d2-bbcc346585c4"),
  72. SHA256: cryptoutil.SHA256(cryptoutil.SHA1("da2775ce-73dd-47ba-b9d2-bbcc346585c4")),
  73. CreatedUnix: 1588568886,
  74. },
  75. &AccessToken{
  76. UserID: 2,
  77. Name: "test2",
  78. Sha1: cryptoutil.SHA256(cryptoutil.SHA1("1b2dccd1-a262-470f-bb8c-7fc73192e9bb"))[:40],
  79. SHA256: cryptoutil.SHA256(cryptoutil.SHA1("1b2dccd1-a262-470f-bb8c-7fc73192e9bb")),
  80. CreatedUnix: 1588568886,
  81. },
  82. &Action{
  83. ID: 1,
  84. UserID: 1,
  85. OpType: ActionCreateBranch,
  86. ActUserID: 1,
  87. ActUserName: "alice",
  88. RepoID: 1,
  89. RepoUserName: "alice",
  90. RepoName: "example",
  91. RefName: "main",
  92. IsPrivate: false,
  93. Content: `{"Len":1,"Commits":[],"CompareURL":""}`,
  94. CreatedUnix: 1588568886,
  95. },
  96. &Action{
  97. ID: 2,
  98. UserID: 1,
  99. OpType: ActionCommitRepo,
  100. ActUserID: 1,
  101. ActUserName: "alice",
  102. RepoID: 1,
  103. RepoUserName: "alice",
  104. RepoName: "example",
  105. RefName: "main",
  106. IsPrivate: false,
  107. Content: `{"Len":1,"Commits":[],"CompareURL":""}`,
  108. CreatedUnix: 1588568886,
  109. },
  110. &Action{
  111. ID: 3,
  112. UserID: 1,
  113. OpType: ActionDeleteBranch,
  114. ActUserID: 1,
  115. ActUserName: "alice",
  116. RepoID: 1,
  117. RepoUserName: "alice",
  118. RepoName: "example",
  119. RefName: "main",
  120. IsPrivate: false,
  121. CreatedUnix: 1588568886,
  122. },
  123. &EmailAddress{
  124. ID: 1,
  125. UserID: 1,
  126. Email: "alice@example.com",
  127. IsActivated: false,
  128. },
  129. &EmailAddress{
  130. ID: 2,
  131. UserID: 2,
  132. Email: "bob@example.com",
  133. IsActivated: true,
  134. },
  135. &Follow{
  136. ID: 1,
  137. UserID: 1,
  138. FollowID: 2,
  139. },
  140. &Follow{
  141. ID: 2,
  142. UserID: 2,
  143. FollowID: 1,
  144. },
  145. &LFSObject{
  146. RepoID: 1,
  147. OID: "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
  148. Size: 100,
  149. Storage: lfsutil.StorageLocal,
  150. CreatedAt: time.Unix(1588568886, 0).UTC(),
  151. },
  152. &LFSObject{
  153. RepoID: 2,
  154. OID: "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
  155. Size: 100,
  156. Storage: lfsutil.StorageLocal,
  157. CreatedAt: time.Unix(1588568886, 0).UTC(),
  158. },
  159. &LoginSource{
  160. Type: auth.PAM,
  161. Name: "My PAM",
  162. IsActived: true,
  163. Provider: pam.NewProvider(&pam.Config{
  164. ServiceName: "PAM service",
  165. }),
  166. CreatedUnix: 1588568886,
  167. UpdatedUnix: 1588572486, // 1 hour later
  168. },
  169. &LoginSource{
  170. Type: auth.GitHub,
  171. Name: "GitHub.com",
  172. IsActived: true,
  173. Provider: github.NewProvider(&github.Config{
  174. APIEndpoint: "https://api.github.com",
  175. }),
  176. CreatedUnix: 1588568886,
  177. },
  178. &Notice{
  179. ID: 1,
  180. Type: NoticeTypeRepository,
  181. Description: "This is a notice",
  182. CreatedUnix: 1588568886,
  183. },
  184. }
  185. for _, val := range vals {
  186. err := db.Create(val).Error
  187. require.NoError(t, err)
  188. }
  189. }
  190. func dumpTables(t *testing.T, db *gorm.DB) {
  191. ctx := context.Background()
  192. for _, table := range Tables {
  193. tableName := getTableType(table)
  194. var buf bytes.Buffer
  195. err := dumpTable(ctx, db, table, &buf)
  196. if err != nil {
  197. t.Fatalf("%s: %v", tableName, err)
  198. }
  199. golden := filepath.Join("testdata", "backup", tableName+".golden.json")
  200. testutil.AssertGolden(t, golden, testutil.Update("TestDumpAndImport"), buf.String())
  201. }
  202. }
  203. func importTables(t *testing.T, db *gorm.DB) {
  204. ctx := context.Background()
  205. for _, table := range Tables {
  206. tableName := getTableType(table)
  207. err := func() error {
  208. golden := filepath.Join("testdata", "backup", tableName+".golden.json")
  209. f, err := os.Open(golden)
  210. if err != nil {
  211. return errors.Wrap(err, "open table file")
  212. }
  213. defer func() { _ = f.Close() }()
  214. return importTable(ctx, db, table, f)
  215. }()
  216. if err != nil {
  217. t.Fatalf("%s: %v", tableName, err)
  218. }
  219. }
  220. }