set_test.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. // Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
  2. // Use of this source code is governed by an MIT-style license that can be
  3. // found in the LICENSE file.
  4. package files
  5. import (
  6. "fmt"
  7. "reflect"
  8. "sort"
  9. "testing"
  10. "github.com/calmh/syncthing/cid"
  11. "github.com/calmh/syncthing/lamport"
  12. "github.com/calmh/syncthing/protocol"
  13. "github.com/calmh/syncthing/scanner"
  14. )
  15. type fileList []scanner.File
  16. func (l fileList) Len() int {
  17. return len(l)
  18. }
  19. func (l fileList) Less(a, b int) bool {
  20. return l[a].Name < l[b].Name
  21. }
  22. func (l fileList) Swap(a, b int) {
  23. l[a], l[b] = l[b], l[a]
  24. }
  25. func TestGlobalSet(t *testing.T) {
  26. m := NewSet()
  27. local := []scanner.File{
  28. scanner.File{Name: "a", Version: 1000},
  29. scanner.File{Name: "b", Version: 1000},
  30. scanner.File{Name: "c", Version: 1000},
  31. scanner.File{Name: "d", Version: 1000},
  32. }
  33. remote := []scanner.File{
  34. scanner.File{Name: "a", Version: 1000},
  35. scanner.File{Name: "b", Version: 1001},
  36. scanner.File{Name: "c", Version: 1002},
  37. scanner.File{Name: "e", Version: 1000},
  38. }
  39. expectedGlobal := []scanner.File{
  40. scanner.File{Name: "a", Version: 1000},
  41. scanner.File{Name: "b", Version: 1001},
  42. scanner.File{Name: "c", Version: 1002},
  43. scanner.File{Name: "d", Version: 1000},
  44. scanner.File{Name: "e", Version: 1000},
  45. }
  46. m.ReplaceWithDelete(cid.LocalID, local)
  47. m.Replace(1, remote)
  48. g := m.Global()
  49. sort.Sort(fileList(g))
  50. sort.Sort(fileList(expectedGlobal))
  51. if !reflect.DeepEqual(g, expectedGlobal) {
  52. t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal)
  53. }
  54. if lb := len(m.files); lb != 7 {
  55. t.Errorf("Num files incorrect %d != 7\n%v", lb, m.files)
  56. }
  57. }
  58. func TestLocalDeleted(t *testing.T) {
  59. m := NewSet()
  60. lamport.Default = lamport.Clock{}
  61. local1 := []scanner.File{
  62. scanner.File{Name: "a", Version: 1000},
  63. scanner.File{Name: "b", Version: 1000},
  64. scanner.File{Name: "c", Version: 1000},
  65. scanner.File{Name: "d", Version: 1000},
  66. scanner.File{Name: "z", Version: 1000, Flags: protocol.FlagDirectory},
  67. }
  68. m.ReplaceWithDelete(cid.LocalID, local1)
  69. m.ReplaceWithDelete(cid.LocalID, []scanner.File{
  70. local1[0],
  71. // [1] removed
  72. local1[2],
  73. local1[3],
  74. local1[4],
  75. })
  76. m.ReplaceWithDelete(cid.LocalID, []scanner.File{
  77. local1[0],
  78. local1[2],
  79. // [3] removed
  80. local1[4],
  81. })
  82. m.ReplaceWithDelete(cid.LocalID, []scanner.File{
  83. local1[0],
  84. local1[2],
  85. // [4] removed
  86. })
  87. expectedGlobal1 := []scanner.File{
  88. local1[0],
  89. scanner.File{Name: "b", Version: 1001, Flags: protocol.FlagDeleted},
  90. local1[2],
  91. scanner.File{Name: "d", Version: 1002, Flags: protocol.FlagDeleted},
  92. scanner.File{Name: "z", Version: 1003, Flags: protocol.FlagDeleted | protocol.FlagDirectory},
  93. }
  94. g := m.Global()
  95. sort.Sort(fileList(g))
  96. sort.Sort(fileList(expectedGlobal1))
  97. if !reflect.DeepEqual(g, expectedGlobal1) {
  98. t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal1)
  99. }
  100. m.ReplaceWithDelete(cid.LocalID, []scanner.File{
  101. local1[0],
  102. // [2] removed
  103. })
  104. expectedGlobal2 := []scanner.File{
  105. local1[0],
  106. scanner.File{Name: "b", Version: 1001, Flags: protocol.FlagDeleted},
  107. scanner.File{Name: "c", Version: 1004, Flags: protocol.FlagDeleted},
  108. scanner.File{Name: "d", Version: 1002, Flags: protocol.FlagDeleted},
  109. scanner.File{Name: "z", Version: 1003, Flags: protocol.FlagDeleted | protocol.FlagDirectory},
  110. }
  111. g = m.Global()
  112. sort.Sort(fileList(g))
  113. sort.Sort(fileList(expectedGlobal2))
  114. if !reflect.DeepEqual(g, expectedGlobal2) {
  115. t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal2)
  116. }
  117. }
  118. func Benchmark10kReplace(b *testing.B) {
  119. var local []scanner.File
  120. for i := 0; i < 10000; i++ {
  121. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  122. }
  123. b.ResetTimer()
  124. for i := 0; i < b.N; i++ {
  125. m := NewSet()
  126. m.ReplaceWithDelete(cid.LocalID, local)
  127. }
  128. }
  129. func Benchmark10kUpdateChg(b *testing.B) {
  130. var remote []scanner.File
  131. for i := 0; i < 10000; i++ {
  132. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  133. }
  134. m := NewSet()
  135. m.Replace(1, remote)
  136. var local []scanner.File
  137. for i := 0; i < 10000; i++ {
  138. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  139. }
  140. m.ReplaceWithDelete(cid.LocalID, local)
  141. b.ResetTimer()
  142. for i := 0; i < b.N; i++ {
  143. b.StopTimer()
  144. for j := range local {
  145. local[j].Version++
  146. }
  147. b.StartTimer()
  148. m.Update(cid.LocalID, local)
  149. }
  150. }
  151. func Benchmark10kUpdateSme(b *testing.B) {
  152. var remote []scanner.File
  153. for i := 0; i < 10000; i++ {
  154. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  155. }
  156. m := NewSet()
  157. m.Replace(1, remote)
  158. var local []scanner.File
  159. for i := 0; i < 10000; i++ {
  160. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  161. }
  162. m.ReplaceWithDelete(cid.LocalID, local)
  163. b.ResetTimer()
  164. for i := 0; i < b.N; i++ {
  165. m.Update(cid.LocalID, local)
  166. }
  167. }
  168. func Benchmark10kNeed2k(b *testing.B) {
  169. var remote []scanner.File
  170. for i := 0; i < 10000; i++ {
  171. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  172. }
  173. m := NewSet()
  174. m.Replace(cid.LocalID+1, remote)
  175. var local []scanner.File
  176. for i := 0; i < 8000; i++ {
  177. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  178. }
  179. for i := 8000; i < 10000; i++ {
  180. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 980})
  181. }
  182. m.ReplaceWithDelete(cid.LocalID, local)
  183. b.ResetTimer()
  184. for i := 0; i < b.N; i++ {
  185. fs := m.Need(cid.LocalID)
  186. if l := len(fs); l != 2000 {
  187. b.Errorf("wrong length %d != 2k", l)
  188. }
  189. }
  190. }
  191. func Benchmark10kHave(b *testing.B) {
  192. var remote []scanner.File
  193. for i := 0; i < 10000; i++ {
  194. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  195. }
  196. m := NewSet()
  197. m.Replace(cid.LocalID+1, remote)
  198. var local []scanner.File
  199. for i := 0; i < 2000; i++ {
  200. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  201. }
  202. for i := 2000; i < 10000; i++ {
  203. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 980})
  204. }
  205. m.ReplaceWithDelete(cid.LocalID, local)
  206. b.ResetTimer()
  207. for i := 0; i < b.N; i++ {
  208. fs := m.Have(cid.LocalID)
  209. if l := len(fs); l != 10000 {
  210. b.Errorf("wrong length %d != 10k", l)
  211. }
  212. }
  213. }
  214. func Benchmark10kGlobal(b *testing.B) {
  215. var remote []scanner.File
  216. for i := 0; i < 10000; i++ {
  217. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  218. }
  219. m := NewSet()
  220. m.Replace(cid.LocalID+1, remote)
  221. var local []scanner.File
  222. for i := 0; i < 2000; i++ {
  223. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
  224. }
  225. for i := 2000; i < 10000; i++ {
  226. local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 980})
  227. }
  228. m.ReplaceWithDelete(cid.LocalID, local)
  229. b.ResetTimer()
  230. for i := 0; i < b.N; i++ {
  231. fs := m.Global()
  232. if l := len(fs); l != 10000 {
  233. b.Errorf("wrong length %d != 10k", l)
  234. }
  235. }
  236. }
  237. func TestGlobalReset(t *testing.T) {
  238. m := NewSet()
  239. local := []scanner.File{
  240. scanner.File{Name: "a", Version: 1000},
  241. scanner.File{Name: "b", Version: 1000},
  242. scanner.File{Name: "c", Version: 1000},
  243. scanner.File{Name: "d", Version: 1000},
  244. }
  245. remote := []scanner.File{
  246. scanner.File{Name: "a", Version: 1000},
  247. scanner.File{Name: "b", Version: 1001},
  248. scanner.File{Name: "c", Version: 1002},
  249. scanner.File{Name: "e", Version: 1000},
  250. }
  251. expectedGlobalKey := map[string]key{
  252. "a": keyFor(local[0]),
  253. "b": keyFor(local[1]),
  254. "c": keyFor(local[2]),
  255. "d": keyFor(local[3]),
  256. }
  257. m.ReplaceWithDelete(cid.LocalID, local)
  258. m.Replace(1, remote)
  259. m.Replace(1, nil)
  260. if !reflect.DeepEqual(m.globalKey, expectedGlobalKey) {
  261. t.Errorf("Global incorrect;\n%v !=\n%v", m.globalKey, expectedGlobalKey)
  262. }
  263. if lb := len(m.files); lb != 4 {
  264. t.Errorf("Num files incorrect %d != 4\n%v", lb, m.files)
  265. }
  266. }
  267. func TestNeed(t *testing.T) {
  268. m := NewSet()
  269. local := []scanner.File{
  270. scanner.File{Name: "a", Version: 1000},
  271. scanner.File{Name: "b", Version: 1000},
  272. scanner.File{Name: "c", Version: 1000},
  273. scanner.File{Name: "d", Version: 1000},
  274. }
  275. remote := []scanner.File{
  276. scanner.File{Name: "a", Version: 1000},
  277. scanner.File{Name: "b", Version: 1001},
  278. scanner.File{Name: "c", Version: 1002},
  279. scanner.File{Name: "e", Version: 1000},
  280. }
  281. shouldNeed := []scanner.File{
  282. scanner.File{Name: "b", Version: 1001},
  283. scanner.File{Name: "c", Version: 1002},
  284. scanner.File{Name: "e", Version: 1000},
  285. }
  286. m.ReplaceWithDelete(cid.LocalID, local)
  287. m.Replace(1, remote)
  288. need := m.Need(0)
  289. sort.Sort(fileList(need))
  290. sort.Sort(fileList(shouldNeed))
  291. if !reflect.DeepEqual(need, shouldNeed) {
  292. t.Errorf("Need incorrect;\n%v !=\n%v", need, shouldNeed)
  293. }
  294. }
  295. func TestChanges(t *testing.T) {
  296. m := NewSet()
  297. local1 := []scanner.File{
  298. scanner.File{Name: "a", Version: 1000},
  299. scanner.File{Name: "b", Version: 1000},
  300. scanner.File{Name: "c", Version: 1000},
  301. scanner.File{Name: "d", Version: 1000},
  302. }
  303. local2 := []scanner.File{
  304. local1[0],
  305. // [1] deleted
  306. local1[2],
  307. scanner.File{Name: "d", Version: 1002},
  308. scanner.File{Name: "e", Version: 1000},
  309. }
  310. m.ReplaceWithDelete(cid.LocalID, local1)
  311. c0 := m.Changes(cid.LocalID)
  312. m.ReplaceWithDelete(cid.LocalID, local2)
  313. c1 := m.Changes(cid.LocalID)
  314. if !(c1 > c0) {
  315. t.Fatal("Change number should have incremented")
  316. }
  317. m.ReplaceWithDelete(cid.LocalID, local2)
  318. c2 := m.Changes(cid.LocalID)
  319. if c2 != c1 {
  320. t.Fatal("Change number should be unchanged")
  321. }
  322. }