blockmap_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at http://mozilla.org/MPL/2.0/.
  6. package db
  7. import (
  8. "testing"
  9. "github.com/syncthing/syncthing/lib/protocol"
  10. "github.com/syndtr/goleveldb/leveldb"
  11. "github.com/syndtr/goleveldb/leveldb/storage"
  12. )
  13. func genBlocks(n int) []protocol.BlockInfo {
  14. b := make([]protocol.BlockInfo, n)
  15. for i := range b {
  16. h := make([]byte, 32)
  17. for j := range h {
  18. h[j] = byte(i + j)
  19. }
  20. b[i].Size = int32(i)
  21. b[i].Hash = h
  22. }
  23. return b
  24. }
  25. var f1, f2, f3 protocol.FileInfo
  26. var folders = []string{"folder1", "folder2"}
  27. func init() {
  28. blocks := genBlocks(30)
  29. f1 = protocol.FileInfo{
  30. Name: "f1",
  31. Blocks: blocks[:10],
  32. }
  33. f2 = protocol.FileInfo{
  34. Name: "f2",
  35. Blocks: blocks[10:20],
  36. }
  37. f3 = protocol.FileInfo{
  38. Name: "f3",
  39. Blocks: blocks[20:],
  40. }
  41. }
  42. func setup() (*leveldb.DB, *BlockFinder) {
  43. // Setup
  44. db, err := leveldb.Open(storage.NewMemStorage(), nil)
  45. if err != nil {
  46. panic(err)
  47. }
  48. return db, NewBlockFinder(db)
  49. }
  50. func dbEmpty(db *leveldb.DB) bool {
  51. iter := db.NewIterator(nil, nil)
  52. defer iter.Release()
  53. if iter.Next() {
  54. return false
  55. }
  56. return true
  57. }
  58. func TestBlockMapAddUpdateWipe(t *testing.T) {
  59. db, f := setup()
  60. if !dbEmpty(db) {
  61. t.Fatal("db not empty")
  62. }
  63. m := NewBlockMap(db, "folder1")
  64. f3.Flags |= protocol.FlagDirectory
  65. err := m.Add([]protocol.FileInfo{f1, f2, f3})
  66. if err != nil {
  67. t.Fatal(err)
  68. }
  69. f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool {
  70. if folder != "folder1" || file != "f1" || index != 0 {
  71. t.Fatal("Mismatch")
  72. }
  73. return true
  74. })
  75. f.Iterate(folders, f2.Blocks[0].Hash, func(folder, file string, index int32) bool {
  76. if folder != "folder1" || file != "f2" || index != 0 {
  77. t.Fatal("Mismatch")
  78. }
  79. return true
  80. })
  81. f.Iterate(folders, f3.Blocks[0].Hash, func(folder, file string, index int32) bool {
  82. t.Fatal("Unexpected block")
  83. return true
  84. })
  85. f3.Flags = f1.Flags
  86. f1.Flags |= protocol.FlagDeleted
  87. f2.Flags |= protocol.FlagInvalid
  88. // Should remove
  89. err = m.Update([]protocol.FileInfo{f1, f2, f3})
  90. if err != nil {
  91. t.Fatal(err)
  92. }
  93. f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool {
  94. t.Fatal("Unexpected block")
  95. return false
  96. })
  97. f.Iterate(folders, f2.Blocks[0].Hash, func(folder, file string, index int32) bool {
  98. t.Fatal("Unexpected block")
  99. return false
  100. })
  101. f.Iterate(folders, f3.Blocks[0].Hash, func(folder, file string, index int32) bool {
  102. if folder != "folder1" || file != "f3" || index != 0 {
  103. t.Fatal("Mismatch")
  104. }
  105. return true
  106. })
  107. err = m.Drop()
  108. if err != nil {
  109. t.Fatal(err)
  110. }
  111. if !dbEmpty(db) {
  112. t.Fatal("db not empty")
  113. }
  114. // Should not add
  115. err = m.Add([]protocol.FileInfo{f1, f2})
  116. if err != nil {
  117. t.Fatal(err)
  118. }
  119. if !dbEmpty(db) {
  120. t.Fatal("db not empty")
  121. }
  122. f1.Flags = 0
  123. f2.Flags = 0
  124. f3.Flags = 0
  125. }
  126. func TestBlockFinderLookup(t *testing.T) {
  127. db, f := setup()
  128. m1 := NewBlockMap(db, "folder1")
  129. m2 := NewBlockMap(db, "folder2")
  130. err := m1.Add([]protocol.FileInfo{f1})
  131. if err != nil {
  132. t.Fatal(err)
  133. }
  134. err = m2.Add([]protocol.FileInfo{f1})
  135. if err != nil {
  136. t.Fatal(err)
  137. }
  138. counter := 0
  139. f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool {
  140. counter++
  141. switch counter {
  142. case 1:
  143. if folder != "folder1" || file != "f1" || index != 0 {
  144. t.Fatal("Mismatch")
  145. }
  146. case 2:
  147. if folder != "folder2" || file != "f1" || index != 0 {
  148. t.Fatal("Mismatch")
  149. }
  150. default:
  151. t.Fatal("Unexpected block")
  152. }
  153. return false
  154. })
  155. if counter != 2 {
  156. t.Fatal("Incorrect count", counter)
  157. }
  158. f1.Flags |= protocol.FlagDeleted
  159. err = m1.Update([]protocol.FileInfo{f1})
  160. if err != nil {
  161. t.Fatal(err)
  162. }
  163. counter = 0
  164. f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool {
  165. counter++
  166. switch counter {
  167. case 1:
  168. if folder != "folder2" || file != "f1" || index != 0 {
  169. t.Fatal("Mismatch")
  170. }
  171. default:
  172. t.Fatal("Unexpected block")
  173. }
  174. return false
  175. })
  176. if counter != 1 {
  177. t.Fatal("Incorrect count")
  178. }
  179. f1.Flags = 0
  180. }
  181. func TestBlockFinderFix(t *testing.T) {
  182. db, f := setup()
  183. iterFn := func(folder, file string, index int32) bool {
  184. return true
  185. }
  186. m := NewBlockMap(db, "folder1")
  187. err := m.Add([]protocol.FileInfo{f1})
  188. if err != nil {
  189. t.Fatal(err)
  190. }
  191. if !f.Iterate(folders, f1.Blocks[0].Hash, iterFn) {
  192. t.Fatal("Block not found")
  193. }
  194. err = f.Fix("folder1", f1.Name, 0, f1.Blocks[0].Hash, f2.Blocks[0].Hash)
  195. if err != nil {
  196. t.Fatal(err)
  197. }
  198. if f.Iterate(folders, f1.Blocks[0].Hash, iterFn) {
  199. t.Fatal("Unexpected block")
  200. }
  201. if !f.Iterate(folders, f2.Blocks[0].Hash, iterFn) {
  202. t.Fatal("Block not found")
  203. }
  204. }