set_test.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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. }
  64. m.ReplaceWithDelete(cid.LocalID, local1)
  65. local2 := []scanner.File{
  66. local1[0],
  67. local1[2],
  68. }
  69. expectedGlobal1 := []scanner.File{
  70. local1[0],
  71. scanner.File{Name: "b", Version: 1001, Flags: protocol.FlagDeleted},
  72. local1[2],
  73. scanner.File{Name: "d", Version: 1002, Flags: protocol.FlagDeleted},
  74. }
  75. m.ReplaceWithDelete(cid.LocalID, local2)
  76. g := m.Global()
  77. sort.Sort(fileList(g))
  78. sort.Sort(fileList(expectedGlobal1))
  79. if !reflect.DeepEqual(g, expectedGlobal1) {
  80. t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal1)
  81. }
  82. local3 := []scanner.File{
  83. local1[0],
  84. }
  85. expectedGlobal2 := []scanner.File{
  86. local1[0],
  87. scanner.File{Name: "b", Version: 1001, Flags: protocol.FlagDeleted},
  88. scanner.File{Name: "c", Version: 1003, Flags: protocol.FlagDeleted},
  89. scanner.File{Name: "d", Version: 1002, Flags: protocol.FlagDeleted},
  90. }
  91. m.ReplaceWithDelete(cid.LocalID, local3)
  92. g = m.Global()
  93. sort.Sort(fileList(g))
  94. sort.Sort(fileList(expectedGlobal2))
  95. if !reflect.DeepEqual(g, expectedGlobal2) {
  96. t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal2)
  97. }
  98. }
  99. func BenchmarkSetLocal10k(b *testing.B) {
  100. m := NewSet()
  101. var local []scanner.File
  102. for i := 0; i < 10000; i++ {
  103. local = append(local, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  104. }
  105. var remote []scanner.File
  106. for i := 0; i < 10000; i++ {
  107. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  108. }
  109. m.Replace(1, remote)
  110. b.ResetTimer()
  111. for i := 0; i < b.N; i++ {
  112. m.ReplaceWithDelete(cid.LocalID, local)
  113. }
  114. }
  115. func BenchmarkSetLocal10(b *testing.B) {
  116. m := NewSet()
  117. var local []scanner.File
  118. for i := 0; i < 10; i++ {
  119. local = append(local, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  120. }
  121. var remote []scanner.File
  122. for i := 0; i < 10000; i++ {
  123. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  124. }
  125. m.Replace(1, remote)
  126. b.ResetTimer()
  127. for i := 0; i < b.N; i++ {
  128. m.ReplaceWithDelete(cid.LocalID, local)
  129. }
  130. }
  131. func BenchmarkAddLocal10k(b *testing.B) {
  132. m := NewSet()
  133. var local []scanner.File
  134. for i := 0; i < 10000; i++ {
  135. local = append(local, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  136. }
  137. var remote []scanner.File
  138. for i := 0; i < 10000; i++ {
  139. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  140. }
  141. m.Replace(1, remote)
  142. m.ReplaceWithDelete(cid.LocalID, local)
  143. b.ResetTimer()
  144. for i := 0; i < b.N; i++ {
  145. b.StopTimer()
  146. for j := range local {
  147. local[j].Version++
  148. }
  149. b.StartTimer()
  150. m.Update(cid.LocalID, local)
  151. }
  152. }
  153. func BenchmarkAddLocal10(b *testing.B) {
  154. m := NewSet()
  155. var local []scanner.File
  156. for i := 0; i < 10; i++ {
  157. local = append(local, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  158. }
  159. var remote []scanner.File
  160. for i := 0; i < 10000; i++ {
  161. remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d"), Version: 1000})
  162. }
  163. m.Replace(1, remote)
  164. m.ReplaceWithDelete(cid.LocalID, local)
  165. b.ResetTimer()
  166. for i := 0; i < b.N; i++ {
  167. for j := range local {
  168. local[j].Version++
  169. }
  170. m.Update(cid.LocalID, local)
  171. }
  172. }
  173. func TestGlobalReset(t *testing.T) {
  174. m := NewSet()
  175. local := []scanner.File{
  176. scanner.File{Name: "a", Version: 1000},
  177. scanner.File{Name: "b", Version: 1000},
  178. scanner.File{Name: "c", Version: 1000},
  179. scanner.File{Name: "d", Version: 1000},
  180. }
  181. remote := []scanner.File{
  182. scanner.File{Name: "a", Version: 1000},
  183. scanner.File{Name: "b", Version: 1001},
  184. scanner.File{Name: "c", Version: 1002},
  185. scanner.File{Name: "e", Version: 1000},
  186. }
  187. expectedGlobalKey := map[string]key{
  188. "a": keyFor(local[0]),
  189. "b": keyFor(local[1]),
  190. "c": keyFor(local[2]),
  191. "d": keyFor(local[3]),
  192. }
  193. m.ReplaceWithDelete(cid.LocalID, local)
  194. m.Replace(1, remote)
  195. m.Replace(1, nil)
  196. if !reflect.DeepEqual(m.globalKey, expectedGlobalKey) {
  197. t.Errorf("Global incorrect;\n%v !=\n%v", m.globalKey, expectedGlobalKey)
  198. }
  199. if lb := len(m.files); lb != 4 {
  200. t.Errorf("Num files incorrect %d != 4\n%v", lb, m.files)
  201. }
  202. }
  203. func TestNeed(t *testing.T) {
  204. m := NewSet()
  205. local := []scanner.File{
  206. scanner.File{Name: "a", Version: 1000},
  207. scanner.File{Name: "b", Version: 1000},
  208. scanner.File{Name: "c", Version: 1000},
  209. scanner.File{Name: "d", Version: 1000},
  210. }
  211. remote := []scanner.File{
  212. scanner.File{Name: "a", Version: 1000},
  213. scanner.File{Name: "b", Version: 1001},
  214. scanner.File{Name: "c", Version: 1002},
  215. scanner.File{Name: "e", Version: 1000},
  216. }
  217. shouldNeed := []scanner.File{
  218. scanner.File{Name: "b", Version: 1001},
  219. scanner.File{Name: "c", Version: 1002},
  220. scanner.File{Name: "e", Version: 1000},
  221. }
  222. m.ReplaceWithDelete(cid.LocalID, local)
  223. m.Replace(1, remote)
  224. need := m.Need(0)
  225. if !reflect.DeepEqual(need, shouldNeed) {
  226. t.Errorf("Need incorrect;\n%v !=\n%v", need, shouldNeed)
  227. }
  228. }
  229. func TestChanges(t *testing.T) {
  230. m := NewSet()
  231. local1 := []scanner.File{
  232. scanner.File{Name: "a", Version: 1000},
  233. scanner.File{Name: "b", Version: 1000},
  234. scanner.File{Name: "c", Version: 1000},
  235. scanner.File{Name: "d", Version: 1000},
  236. }
  237. local2 := []scanner.File{
  238. local1[0],
  239. // [1] deleted
  240. local1[2],
  241. scanner.File{Name: "d", Version: 1002},
  242. scanner.File{Name: "e", Version: 1000},
  243. }
  244. m.ReplaceWithDelete(cid.LocalID, local1)
  245. c0 := m.Changes(cid.LocalID)
  246. m.ReplaceWithDelete(cid.LocalID, local2)
  247. c1 := m.Changes(cid.LocalID)
  248. if !(c1 > c0) {
  249. t.Fatal("Change number should have incremented")
  250. }
  251. m.ReplaceWithDelete(cid.LocalID, local2)
  252. c2 := m.Changes(cid.LocalID)
  253. if c2 != c1 {
  254. t.Fatal("Change number should be unchanged")
  255. }
  256. }