db_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package manager
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "sort"
  8. "testing"
  9. "time"
  10. "github.com/alicebob/miniredis"
  11. . "github.com/smartystreets/goconvey/convey"
  12. . "github.com/tuna/tunasync/internal"
  13. )
  14. func SortMirrorStatus(status []MirrorStatus) {
  15. sort.Slice(status, func(l, r int) bool {
  16. return status[l].Name < status[r].Name
  17. })
  18. }
  19. func DBAdapterTest(db dbAdapter) {
  20. var err error
  21. testWorkerIDs := []string{"test_worker1", "test_worker2"}
  22. Convey("create worker", func() {
  23. for _, id := range testWorkerIDs {
  24. w := WorkerStatus{
  25. ID: id,
  26. Token: "token_" + id,
  27. LastOnline: time.Now(),
  28. LastRegister: time.Now(),
  29. }
  30. _, err = db.CreateWorker(w)
  31. So(err, ShouldBeNil)
  32. }
  33. Convey("get existent worker", func() {
  34. _, err := db.GetWorker(testWorkerIDs[0])
  35. So(err, ShouldBeNil)
  36. })
  37. Convey("list existent workers", func() {
  38. ws, err := db.ListWorkers()
  39. So(err, ShouldBeNil)
  40. So(len(ws), ShouldEqual, 2)
  41. })
  42. Convey("get non-existent worker", func() {
  43. _, err := db.GetWorker("invalid workerID")
  44. So(err, ShouldNotBeNil)
  45. })
  46. Convey("delete existent worker", func() {
  47. err := db.DeleteWorker(testWorkerIDs[0])
  48. So(err, ShouldBeNil)
  49. _, err = db.GetWorker(testWorkerIDs[0])
  50. So(err, ShouldNotBeNil)
  51. ws, err := db.ListWorkers()
  52. So(err, ShouldBeNil)
  53. So(len(ws), ShouldEqual, 1)
  54. })
  55. Convey("delete non-existent worker", func() {
  56. err := db.DeleteWorker("invalid workerID")
  57. So(err, ShouldNotBeNil)
  58. ws, err := db.ListWorkers()
  59. So(err, ShouldBeNil)
  60. So(len(ws), ShouldEqual, 2)
  61. })
  62. })
  63. Convey("update mirror status", func() {
  64. status := []MirrorStatus{
  65. {
  66. Name: "arch-sync1",
  67. Worker: testWorkerIDs[0],
  68. IsMaster: true,
  69. Status: Success,
  70. LastUpdate: time.Now(),
  71. LastStarted: time.Now().Add(-time.Minute),
  72. LastEnded: time.Now(),
  73. Upstream: "mirrors.tuna.tsinghua.edu.cn",
  74. Size: "3GB",
  75. },
  76. {
  77. Name: "arch-sync2",
  78. Worker: testWorkerIDs[1],
  79. IsMaster: true,
  80. Status: Disabled,
  81. LastUpdate: time.Now().Add(-time.Hour),
  82. LastStarted: time.Now().Add(-time.Minute),
  83. LastEnded: time.Now(),
  84. Upstream: "mirrors.tuna.tsinghua.edu.cn",
  85. Size: "4GB",
  86. },
  87. {
  88. Name: "arch-sync3",
  89. Worker: testWorkerIDs[1],
  90. IsMaster: true,
  91. Status: Success,
  92. LastUpdate: time.Now().Add(-time.Minute),
  93. LastStarted: time.Now().Add(-time.Second),
  94. LastEnded: time.Now(),
  95. Upstream: "mirrors.tuna.tsinghua.edu.cn",
  96. Size: "4GB",
  97. },
  98. }
  99. SortMirrorStatus(status)
  100. for _, s := range status {
  101. _, err := db.UpdateMirrorStatus(s.Worker, s.Name, s)
  102. So(err, ShouldBeNil)
  103. }
  104. Convey("get mirror status", func() {
  105. m, err := db.GetMirrorStatus(testWorkerIDs[0], status[0].Name)
  106. So(err, ShouldBeNil)
  107. expectedJSON, err := json.Marshal(status[0])
  108. So(err, ShouldBeNil)
  109. actualJSON, err := json.Marshal(m)
  110. So(err, ShouldBeNil)
  111. So(string(actualJSON), ShouldEqual, string(expectedJSON))
  112. })
  113. Convey("list mirror status", func() {
  114. ms, err := db.ListMirrorStatus(testWorkerIDs[0])
  115. So(err, ShouldBeNil)
  116. expectedJSON, err := json.Marshal([]MirrorStatus{status[0]})
  117. So(err, ShouldBeNil)
  118. actualJSON, err := json.Marshal(ms)
  119. So(err, ShouldBeNil)
  120. So(string(actualJSON), ShouldEqual, string(expectedJSON))
  121. })
  122. Convey("list all mirror status", func() {
  123. ms, err := db.ListAllMirrorStatus()
  124. So(err, ShouldBeNil)
  125. SortMirrorStatus(ms)
  126. expectedJSON, err := json.Marshal(status)
  127. So(err, ShouldBeNil)
  128. actualJSON, err := json.Marshal(ms)
  129. So(err, ShouldBeNil)
  130. So(string(actualJSON), ShouldEqual, string(expectedJSON))
  131. })
  132. Convey("flush disabled jobs", func() {
  133. ms, err := db.ListAllMirrorStatus()
  134. So(err, ShouldBeNil)
  135. So(len(ms), ShouldEqual, 3)
  136. err = db.FlushDisabledJobs()
  137. So(err, ShouldBeNil)
  138. ms, err = db.ListAllMirrorStatus()
  139. So(err, ShouldBeNil)
  140. So(len(ms), ShouldEqual, 2)
  141. })
  142. })
  143. }
  144. func TestDBAdapter(t *testing.T) {
  145. Convey("boltAdapter should work", t, func() {
  146. tmpDir, err := os.MkdirTemp("", "tunasync")
  147. defer os.RemoveAll(tmpDir)
  148. So(err, ShouldBeNil)
  149. dbType, dbFile := "bolt", filepath.Join(tmpDir, "bolt.db")
  150. boltDB, err := makeDBAdapter(dbType, dbFile)
  151. So(err, ShouldBeNil)
  152. defer func() {
  153. // close boltDB
  154. err := boltDB.Close()
  155. So(err, ShouldBeNil)
  156. }()
  157. DBAdapterTest(boltDB)
  158. })
  159. Convey("redisAdapter should work", t, func() {
  160. mr, err := miniredis.Run()
  161. So(err, ShouldBeNil)
  162. addr := fmt.Sprintf("redis://%s", mr.Addr())
  163. redisDB, err := makeDBAdapter("redis", addr)
  164. So(err, ShouldBeNil)
  165. defer func() {
  166. // close redisDB
  167. err := redisDB.Close()
  168. So(err, ShouldBeNil)
  169. mr.Close()
  170. }()
  171. DBAdapterTest(redisDB)
  172. })
  173. Convey("badgerAdapter should work", t, func() {
  174. tmpDir, err := os.MkdirTemp("", "tunasync")
  175. defer os.RemoveAll(tmpDir)
  176. So(err, ShouldBeNil)
  177. dbType, dbFile := "badger", filepath.Join(tmpDir, "badger.db")
  178. badgerDB, err := makeDBAdapter(dbType, dbFile)
  179. So(err, ShouldBeNil)
  180. defer func() {
  181. // close badgerDB
  182. err := badgerDB.Close()
  183. So(err, ShouldBeNil)
  184. }()
  185. DBAdapterTest(badgerDB)
  186. })
  187. Convey("leveldbAdapter should work", t, func() {
  188. tmpDir, err := os.MkdirTemp("", "tunasync")
  189. defer os.RemoveAll(tmpDir)
  190. So(err, ShouldBeNil)
  191. dbType, dbFile := "leveldb", filepath.Join(tmpDir, "leveldb.db")
  192. leveldbDB, err := makeDBAdapter(dbType, dbFile)
  193. So(err, ShouldBeNil)
  194. defer func() {
  195. // close leveldbDB
  196. err := leveldbDB.Close()
  197. So(err, ShouldBeNil)
  198. }()
  199. DBAdapterTest(leveldbDB)
  200. })
  201. }