1
0

backup_test.go 5.5 KB

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