set_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. package files
  2. import (
  3. "fmt"
  4. "reflect"
  5. "sort"
  6. "testing"
  7. "github.com/calmh/syncthing/cid"
  8. "github.com/calmh/syncthing/lamport"
  9. "github.com/calmh/syncthing/protocol"
  10. "github.com/calmh/syncthing/scanner"
  11. )
  12. type fileList []scanner.File
  13. func (l fileList) Len() int {
  14. return len(l)
  15. }
  16. func (l fileList) Less(a, b int) bool {
  17. return l[a].Name < l[b].Name
  18. }
  19. func (l fileList) Swap(a, b int) {
  20. l[a], l[b] = l[b], l[a]
  21. }
  22. func TestGlobalSet(t *testing.T) {
  23. m := NewSet()
  24. local := []scanner.File{
  25. scanner.File{Name: "a", Version: 1000},
  26. scanner.File{Name: "b", Version: 1000},
  27. scanner.File{Name: "c", Version: 1000},
  28. scanner.File{Name: "d", Version: 1000},
  29. }
  30. remote := []scanner.File{
  31. scanner.File{Name: "a", Version: 1000},
  32. scanner.File{Name: "b", Version: 1001},
  33. scanner.File{Name: "c", Version: 1002},
  34. scanner.File{Name: "e", Version: 1000},
  35. }
  36. expectedGlobal := []scanner.File{
  37. scanner.File{Name: "a", Version: 1000},
  38. scanner.File{Name: "b", Version: 1001},
  39. scanner.File{Name: "c", Version: 1002},
  40. scanner.File{Name: "d", Version: 1000},
  41. scanner.File{Name: "e", Version: 1000},
  42. }
  43. m.ReplaceWithDelete(cid.LocalID, local)
  44. m.Replace(1, remote)
  45. g := m.Global()
  46. sort.Sort(fileList(g))
  47. sort.Sort(fileList(expectedGlobal))
  48. if !reflect.DeepEqual(g, expectedGlobal) {
  49. t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal)
  50. }
  51. if lb := len(m.files); lb != 7 {
  52. t.Errorf("Num files incorrect %d != 7\n%v", lb, m.files)
  53. }
  54. }
  55. func TestLocalDeleted(t *testing.T) {
  56. m := NewSet()
  57. lamport.Default = lamport.Clock{}
  58. local1 := []scanner.File{
  59. scanner.File{Name: "a", Version: 1000},
  60. scanner.File{Name: "b", Version: 1000},
  61. scanner.File{Name: "c", Version: 1000},
  62. scanner.File{Name: "d", Version: 1000},
  63. scanner.File{Name: "z", Version: 1000, Flags: protocol.FlagDirectory},
  64. }
  65. m.ReplaceWithDelete(cid.LocalID, local1)
  66. local2 := []scanner.File{
  67. local1[0],
  68. local1[2],
  69. }
  70. expectedGlobal1 := []scanner.File{
  71. local1[0],
  72. scanner.File{Name: "b", Version: 1001, Flags: protocol.FlagDeleted},
  73. local1[2],
  74. scanner.File{Name: "d", Version: 1002, Flags: protocol.FlagDeleted},
  75. scanner.File{Name: "z", Version: 1003, Flags: protocol.FlagDeleted | protocol.FlagDirectory},
  76. }
  77. m.ReplaceWithDelete(cid.LocalID, local2)
  78. g := m.Global()
  79. sort.Sort(fileList(g))
  80. sort.Sort(fileList(expectedGlobal1))
  81. if !reflect.DeepEqual(g, expectedGlobal1) {
  82. t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal1)
  83. }
  84. local3 := []scanner.File{
  85. local1[0],
  86. }
  87. expectedGlobal2 := []scanner.File{
  88. local1[0],
  89. scanner.File{Name: "b", Version: 1001, Flags: protocol.FlagDeleted},
  90. scanner.File{Name: "c", Version: 1004, Flags: protocol.FlagDeleted},
  91. scanner.File{Name: "d", Version: 1002, Flags: protocol.FlagDeleted},
  92. scanner.File{Name: "z", Version: 1003, Flags: protocol.FlagDeleted | protocol.FlagDirectory},
  93. }
  94. m.ReplaceWithDelete(cid.LocalID, local3)
  95. g = m.Global()
  96. sort.Sort(fileList(g))
  97. sort.Sort(fileList(expectedGlobal2))
  98. if !reflect.DeepEqual(g, expectedGlobal2) {
  99. t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal2)
  100. }
  101. }
  102. func BenchmarkSetLocal10k(b *testing.B) {
  103. m := NewSet()
  104. var local []scanner.File
  105. for i := 0; i < 10000; i++ {
  106. local = append(local, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  107. }
  108. var remote []scanner.File
  109. for i := 0; i < 10000; i++ {
  110. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  111. }
  112. m.Replace(1, remote)
  113. b.ResetTimer()
  114. for i := 0; i < b.N; i++ {
  115. m.ReplaceWithDelete(cid.LocalID, local)
  116. }
  117. }
  118. func BenchmarkSetLocal10(b *testing.B) {
  119. m := NewSet()
  120. var local []scanner.File
  121. for i := 0; i < 10; i++ {
  122. local = append(local, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  123. }
  124. var remote []scanner.File
  125. for i := 0; i < 10000; i++ {
  126. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  127. }
  128. m.Replace(1, remote)
  129. b.ResetTimer()
  130. for i := 0; i < b.N; i++ {
  131. m.ReplaceWithDelete(cid.LocalID, local)
  132. }
  133. }
  134. func BenchmarkAddLocal10k(b *testing.B) {
  135. m := NewSet()
  136. var local []scanner.File
  137. for i := 0; i < 10000; i++ {
  138. local = append(local, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  139. }
  140. var remote []scanner.File
  141. for i := 0; i < 10000; i++ {
  142. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  143. }
  144. m.Replace(1, remote)
  145. m.ReplaceWithDelete(cid.LocalID, local)
  146. b.ResetTimer()
  147. for i := 0; i < b.N; i++ {
  148. b.StopTimer()
  149. for j := range local {
  150. local[j].Version++
  151. }
  152. b.StartTimer()
  153. m.Update(cid.LocalID, local)
  154. }
  155. }
  156. func BenchmarkAddLocal10(b *testing.B) {
  157. m := NewSet()
  158. var local []scanner.File
  159. for i := 0; i < 10; i++ {
  160. local = append(local, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  161. }
  162. var remote []scanner.File
  163. for i := 0; i < 10000; i++ {
  164. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  165. }
  166. m.Replace(1, remote)
  167. m.ReplaceWithDelete(cid.LocalID, local)
  168. b.ResetTimer()
  169. for i := 0; i < b.N; i++ {
  170. for j := range local {
  171. local[j].Version++
  172. }
  173. m.Update(cid.LocalID, local)
  174. }
  175. }
  176. func TestGlobalReset(t *testing.T) {
  177. m := NewSet()
  178. local := []scanner.File{
  179. scanner.File{Name: "a", Version: 1000},
  180. scanner.File{Name: "b", Version: 1000},
  181. scanner.File{Name: "c", Version: 1000},
  182. scanner.File{Name: "d", Version: 1000},
  183. }
  184. remote := []scanner.File{
  185. scanner.File{Name: "a", Version: 1000},
  186. scanner.File{Name: "b", Version: 1001},
  187. scanner.File{Name: "c", Version: 1002},
  188. scanner.File{Name: "e", Version: 1000},
  189. }
  190. expectedGlobalKey := map[string]key{
  191. "a": keyFor(local[0]),
  192. "b": keyFor(local[1]),
  193. "c": keyFor(local[2]),
  194. "d": keyFor(local[3]),
  195. }
  196. m.ReplaceWithDelete(cid.LocalID, local)
  197. m.Replace(1, remote)
  198. m.Replace(1, nil)
  199. if !reflect.DeepEqual(m.globalKey, expectedGlobalKey) {
  200. t.Errorf("Global incorrect;\n%v !=\n%v", m.globalKey, expectedGlobalKey)
  201. }
  202. if lb := len(m.files); lb != 4 {
  203. t.Errorf("Num files incorrect %d != 4\n%v", lb, m.files)
  204. }
  205. }
  206. func TestNeed(t *testing.T) {
  207. m := NewSet()
  208. local := []scanner.File{
  209. scanner.File{Name: "a", Version: 1000},
  210. scanner.File{Name: "b", Version: 1000},
  211. scanner.File{Name: "c", Version: 1000},
  212. scanner.File{Name: "d", Version: 1000},
  213. }
  214. remote := []scanner.File{
  215. scanner.File{Name: "a", Version: 1000},
  216. scanner.File{Name: "b", Version: 1001},
  217. scanner.File{Name: "c", Version: 1002},
  218. scanner.File{Name: "e", Version: 1000},
  219. }
  220. shouldNeed := []scanner.File{
  221. scanner.File{Name: "b", Version: 1001},
  222. scanner.File{Name: "c", Version: 1002},
  223. scanner.File{Name: "e", Version: 1000},
  224. }
  225. m.ReplaceWithDelete(cid.LocalID, local)
  226. m.Replace(1, remote)
  227. need := m.Need(0)
  228. if !reflect.DeepEqual(need, shouldNeed) {
  229. t.Errorf("Need incorrect;\n%v !=\n%v", need, shouldNeed)
  230. }
  231. }
  232. func TestChanges(t *testing.T) {
  233. m := NewSet()
  234. local1 := []scanner.File{
  235. scanner.File{Name: "a", Version: 1000},
  236. scanner.File{Name: "b", Version: 1000},
  237. scanner.File{Name: "c", Version: 1000},
  238. scanner.File{Name: "d", Version: 1000},
  239. }
  240. local2 := []scanner.File{
  241. local1[0],
  242. // [1] deleted
  243. local1[2],
  244. scanner.File{Name: "d", Version: 1002},
  245. scanner.File{Name: "e", Version: 1000},
  246. }
  247. m.ReplaceWithDelete(cid.LocalID, local1)
  248. c0 := m.Changes(cid.LocalID)
  249. m.ReplaceWithDelete(cid.LocalID, local2)
  250. c1 := m.Changes(cid.LocalID)
  251. if !(c1 > c0) {
  252. t.Fatal("Change number should have incremented")
  253. }
  254. m.ReplaceWithDelete(cid.LocalID, local2)
  255. c2 := m.Changes(cid.LocalID)
  256. if c2 != c1 {
  257. t.Fatal("Change number should be unchanged")
  258. }
  259. }