vector_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. // Copyright (C) 2015 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 https://mozilla.org/MPL/2.0/.
  6. package protocol
  7. import (
  8. "math"
  9. "testing"
  10. )
  11. func TestUpdate(t *testing.T) {
  12. var v Vector
  13. // Append
  14. v = v.updateWithNow(42, 5)
  15. expected := Vector{Counters: []Counter{{ID: 42, Value: 5}}}
  16. if v.Compare(expected) != Equal {
  17. t.Errorf("Update error, %+v != %+v", v, expected)
  18. }
  19. // Insert at front
  20. v = v.updateWithNow(36, 6)
  21. expected = Vector{Counters: []Counter{{ID: 36, Value: 6}, {ID: 42, Value: 5}}}
  22. if v.Compare(expected) != Equal {
  23. t.Errorf("Update error, %+v != %+v", v, expected)
  24. }
  25. // Insert in middle
  26. v = v.updateWithNow(37, 7)
  27. expected = Vector{Counters: []Counter{{ID: 36, Value: 6}, {ID: 37, Value: 7}, {ID: 42, Value: 5}}}
  28. if v.Compare(expected) != Equal {
  29. t.Errorf("Update error, %+v != %+v", v, expected)
  30. }
  31. // Update existing
  32. v = v.updateWithNow(37, 1)
  33. expected = Vector{Counters: []Counter{{ID: 36, Value: 6}, {ID: 37, Value: 8}, {ID: 42, Value: 5}}}
  34. if v.Compare(expected) != Equal {
  35. t.Errorf("Update error, %+v != %+v", v, expected)
  36. }
  37. // Update existing with higher current time
  38. v = v.updateWithNow(37, 100)
  39. expected = Vector{Counters: []Counter{{ID: 36, Value: 6}, {ID: 37, Value: 100}, {ID: 42, Value: 5}}}
  40. if v.Compare(expected) != Equal {
  41. t.Errorf("Update error, %+v != %+v", v, expected)
  42. }
  43. // Update existing with lower current time
  44. v = v.updateWithNow(37, 50)
  45. expected = Vector{Counters: []Counter{{ID: 36, Value: 6}, {ID: 37, Value: 101}, {ID: 42, Value: 5}}}
  46. if v.Compare(expected) != Equal {
  47. t.Errorf("Update error, %+v != %+v", v, expected)
  48. }
  49. }
  50. func TestCopy(t *testing.T) {
  51. v0 := Vector{Counters: []Counter{{ID: 42, Value: 1}}}
  52. v1 := v0.Copy()
  53. v1.Update(42)
  54. if v0.Compare(v1) != Lesser {
  55. t.Errorf("Copy error, %+v should be ancestor of %+v", v0, v1)
  56. }
  57. }
  58. func TestMerge(t *testing.T) {
  59. testcases := []struct {
  60. a, b, m Vector
  61. }{
  62. // No-ops
  63. {
  64. Vector{},
  65. Vector{},
  66. Vector{},
  67. },
  68. {
  69. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  70. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  71. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  72. },
  73. // Appends
  74. {
  75. Vector{},
  76. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  77. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  78. },
  79. {
  80. Vector{Counters: []Counter{{ID: 22, Value: 1}}},
  81. Vector{Counters: []Counter{{ID: 42, Value: 1}}},
  82. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  83. },
  84. {
  85. Vector{Counters: []Counter{{ID: 22, Value: 1}}},
  86. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  87. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  88. },
  89. // Insert
  90. {
  91. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  92. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 23, Value: 2}, {ID: 42, Value: 1}}},
  93. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 23, Value: 2}, {ID: 42, Value: 1}}},
  94. },
  95. {
  96. Vector{Counters: []Counter{{ID: 42, Value: 1}}},
  97. Vector{Counters: []Counter{{ID: 22, Value: 1}}},
  98. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 1}}},
  99. },
  100. // Update
  101. {
  102. Vector{Counters: []Counter{{ID: 22, Value: 1}, {ID: 42, Value: 2}}},
  103. Vector{Counters: []Counter{{ID: 22, Value: 2}, {ID: 42, Value: 1}}},
  104. Vector{Counters: []Counter{{ID: 22, Value: 2}, {ID: 42, Value: 2}}},
  105. },
  106. // All of the above
  107. {
  108. Vector{Counters: []Counter{{ID: 10, Value: 1}, {ID: 20, Value: 2}, {ID: 30, Value: 1}}},
  109. Vector{Counters: []Counter{{ID: 5, Value: 1}, {ID: 10, Value: 2}, {ID: 15, Value: 1}, {ID: 20, Value: 1}, {ID: 25, Value: 1}, {ID: 35, Value: 1}}},
  110. Vector{Counters: []Counter{{ID: 5, Value: 1}, {ID: 10, Value: 2}, {ID: 15, Value: 1}, {ID: 20, Value: 2}, {ID: 25, Value: 1}, {ID: 30, Value: 1}, {ID: 35, Value: 1}}},
  111. },
  112. }
  113. for i, tc := range testcases {
  114. if m := tc.a.Merge(tc.b); m.Compare(tc.m) != Equal {
  115. t.Errorf("%d: %+v.Merge(%+v) == %+v (expected %+v)", i, tc.a, tc.b, m, tc.m)
  116. }
  117. }
  118. }
  119. func TestCounterValue(t *testing.T) {
  120. v0 := Vector{Counters: []Counter{{ID: 42, Value: 1}, {ID: 64, Value: 5}}}
  121. if v0.Counter(42) != 1 {
  122. t.Errorf("Counter error, %d != %d", v0.Counter(42), 1)
  123. }
  124. if v0.Counter(64) != 5 {
  125. t.Errorf("Counter error, %d != %d", v0.Counter(64), 5)
  126. }
  127. if v0.Counter(72) != 0 {
  128. t.Errorf("Counter error, %d != %d", v0.Counter(72), 0)
  129. }
  130. }
  131. func TestCompare(t *testing.T) {
  132. testcases := []struct {
  133. a, b Vector
  134. r Ordering
  135. }{
  136. // Empty vectors are identical
  137. {Vector{}, Vector{}, Equal},
  138. {Vector{}, Vector{Counters: []Counter{{ID: 42, Value: 0}}}, Equal},
  139. {Vector{Counters: []Counter{{ID: 42, Value: 0}}}, Vector{}, Equal},
  140. // Zero is the implied value for a missing Counter
  141. {
  142. Vector{Counters: []Counter{{ID: 42, Value: 0}}},
  143. Vector{Counters: []Counter{{ID: 77, Value: 0}}},
  144. Equal,
  145. },
  146. // Equal vectors are equal
  147. {
  148. Vector{Counters: []Counter{{ID: 42, Value: 33}}},
  149. Vector{Counters: []Counter{{ID: 42, Value: 33}}},
  150. Equal,
  151. },
  152. {
  153. Vector{Counters: []Counter{{ID: 42, Value: 33}, {ID: 77, Value: 24}}},
  154. Vector{Counters: []Counter{{ID: 42, Value: 33}, {ID: 77, Value: 24}}},
  155. Equal,
  156. },
  157. // These a-vectors are all greater than the b-vector
  158. {
  159. Vector{Counters: []Counter{{ID: 42, Value: 1}}},
  160. Vector{},
  161. Greater,
  162. },
  163. {
  164. Vector{Counters: []Counter{{ID: 0, Value: 1}}},
  165. Vector{Counters: []Counter{{ID: 0, Value: 0}}},
  166. Greater,
  167. },
  168. {
  169. Vector{Counters: []Counter{{ID: 42, Value: 1}}},
  170. Vector{Counters: []Counter{{ID: 42, Value: 0}}},
  171. Greater,
  172. },
  173. {
  174. Vector{Counters: []Counter{{ID: math.MaxUint64, Value: 1}}},
  175. Vector{Counters: []Counter{{ID: math.MaxUint64, Value: 0}}},
  176. Greater,
  177. },
  178. {
  179. Vector{Counters: []Counter{{ID: 0, Value: math.MaxUint64}}},
  180. Vector{Counters: []Counter{{ID: 0, Value: 0}}},
  181. Greater,
  182. },
  183. {
  184. Vector{Counters: []Counter{{ID: 42, Value: math.MaxUint64}}},
  185. Vector{Counters: []Counter{{ID: 42, Value: 0}}},
  186. Greater,
  187. },
  188. {
  189. Vector{Counters: []Counter{{ID: math.MaxUint64, Value: math.MaxUint64}}},
  190. Vector{Counters: []Counter{{ID: math.MaxUint64, Value: 0}}},
  191. Greater,
  192. },
  193. {
  194. Vector{Counters: []Counter{{ID: 0, Value: math.MaxUint64}}},
  195. Vector{Counters: []Counter{{ID: 0, Value: math.MaxUint64 - 1}}},
  196. Greater,
  197. },
  198. {
  199. Vector{Counters: []Counter{{ID: 42, Value: math.MaxUint64}}},
  200. Vector{Counters: []Counter{{ID: 42, Value: math.MaxUint64 - 1}}},
  201. Greater,
  202. },
  203. {
  204. Vector{Counters: []Counter{{ID: math.MaxUint64, Value: math.MaxUint64}}},
  205. Vector{Counters: []Counter{{ID: math.MaxUint64, Value: math.MaxUint64 - 1}}},
  206. Greater,
  207. },
  208. {
  209. Vector{Counters: []Counter{{ID: 42, Value: 2}}},
  210. Vector{Counters: []Counter{{ID: 42, Value: 1}}},
  211. Greater,
  212. },
  213. {
  214. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 2}}},
  215. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 1}}},
  216. Greater,
  217. },
  218. {
  219. Vector{Counters: []Counter{{ID: 42, Value: 2}, {ID: 77, Value: 3}}},
  220. Vector{Counters: []Counter{{ID: 42, Value: 1}, {ID: 77, Value: 3}}},
  221. Greater,
  222. },
  223. {
  224. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 2}, {ID: 77, Value: 3}}},
  225. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 1}, {ID: 77, Value: 3}}},
  226. Greater,
  227. },
  228. {
  229. Vector{Counters: []Counter{{ID: 22, Value: 23}, {ID: 42, Value: 2}, {ID: 77, Value: 4}}},
  230. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 1}, {ID: 77, Value: 3}}},
  231. Greater,
  232. },
  233. // These a-vectors are all lesser than the b-vector
  234. {Vector{}, Vector{Counters: []Counter{{ID: 42, Value: 1}}}, Lesser},
  235. {
  236. Vector{Counters: []Counter{{ID: 42, Value: 0}}},
  237. Vector{Counters: []Counter{{ID: 42, Value: 1}}},
  238. Lesser,
  239. },
  240. {
  241. Vector{Counters: []Counter{{ID: 42, Value: 1}}},
  242. Vector{Counters: []Counter{{ID: 42, Value: 2}}},
  243. Lesser,
  244. },
  245. {
  246. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 1}}},
  247. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 2}}},
  248. Lesser,
  249. },
  250. {
  251. Vector{Counters: []Counter{{ID: 42, Value: 1}, {ID: 77, Value: 3}}},
  252. Vector{Counters: []Counter{{ID: 42, Value: 2}, {ID: 77, Value: 3}}},
  253. Lesser,
  254. },
  255. {
  256. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 1}, {ID: 77, Value: 3}}},
  257. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 2}, {ID: 77, Value: 3}}},
  258. Lesser,
  259. },
  260. {
  261. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 1}, {ID: 77, Value: 3}}},
  262. Vector{Counters: []Counter{{ID: 22, Value: 23}, {ID: 42, Value: 2}, {ID: 77, Value: 4}}},
  263. Lesser,
  264. },
  265. // These are all in conflict
  266. {
  267. Vector{Counters: []Counter{{ID: 42, Value: 2}}},
  268. Vector{Counters: []Counter{{ID: 43, Value: 1}}},
  269. ConcurrentGreater,
  270. },
  271. {
  272. Vector{Counters: []Counter{{ID: 43, Value: 1}}},
  273. Vector{Counters: []Counter{{ID: 42, Value: 2}}},
  274. ConcurrentLesser,
  275. },
  276. {
  277. Vector{Counters: []Counter{{ID: 22, Value: 23}, {ID: 42, Value: 1}}},
  278. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 2}}},
  279. ConcurrentGreater,
  280. },
  281. {
  282. Vector{Counters: []Counter{{ID: 22, Value: 21}, {ID: 42, Value: 2}}},
  283. Vector{Counters: []Counter{{ID: 22, Value: 22}, {ID: 42, Value: 1}}},
  284. ConcurrentLesser,
  285. },
  286. {
  287. Vector{Counters: []Counter{{ID: 22, Value: 21}, {ID: 42, Value: 2}, {ID: 43, Value: 1}}},
  288. Vector{Counters: []Counter{{ID: 20, Value: 1}, {ID: 22, Value: 22}, {ID: 42, Value: 1}}},
  289. ConcurrentLesser,
  290. },
  291. }
  292. for i, tc := range testcases {
  293. // Test real Compare
  294. if r := tc.a.Compare(tc.b); r != tc.r {
  295. t.Errorf("%d: %+v.Compare(%+v) == %v (expected %v)", i, tc.a, tc.b, r, tc.r)
  296. }
  297. // Test convenience functions
  298. switch tc.r {
  299. case Greater:
  300. if tc.a.Equal(tc.b) {
  301. t.Errorf("%+v == %+v", tc.a, tc.b)
  302. }
  303. if tc.a.Concurrent(tc.b) {
  304. t.Errorf("%+v concurrent %+v", tc.a, tc.b)
  305. }
  306. if !tc.a.GreaterEqual(tc.b) {
  307. t.Errorf("%+v not >= %+v", tc.a, tc.b)
  308. }
  309. if tc.a.LesserEqual(tc.b) {
  310. t.Errorf("%+v <= %+v", tc.a, tc.b)
  311. }
  312. case Lesser:
  313. if tc.a.Concurrent(tc.b) {
  314. t.Errorf("%+v concurrent %+v", tc.a, tc.b)
  315. }
  316. if tc.a.Equal(tc.b) {
  317. t.Errorf("%+v == %+v", tc.a, tc.b)
  318. }
  319. if tc.a.GreaterEqual(tc.b) {
  320. t.Errorf("%+v >= %+v", tc.a, tc.b)
  321. }
  322. if !tc.a.LesserEqual(tc.b) {
  323. t.Errorf("%+v not <= %+v", tc.a, tc.b)
  324. }
  325. case Equal:
  326. if tc.a.Concurrent(tc.b) {
  327. t.Errorf("%+v concurrent %+v", tc.a, tc.b)
  328. }
  329. if !tc.a.Equal(tc.b) {
  330. t.Errorf("%+v not == %+v", tc.a, tc.b)
  331. }
  332. if !tc.a.GreaterEqual(tc.b) {
  333. t.Errorf("%+v not <= %+v", tc.a, tc.b)
  334. }
  335. if !tc.a.LesserEqual(tc.b) {
  336. t.Errorf("%+v not <= %+v", tc.a, tc.b)
  337. }
  338. case ConcurrentLesser, ConcurrentGreater:
  339. if !tc.a.Concurrent(tc.b) {
  340. t.Errorf("%+v not concurrent %+v", tc.a, tc.b)
  341. }
  342. if tc.a.Equal(tc.b) {
  343. t.Errorf("%+v == %+v", tc.a, tc.b)
  344. }
  345. if tc.a.GreaterEqual(tc.b) {
  346. t.Errorf("%+v >= %+v", tc.a, tc.b)
  347. }
  348. if tc.a.LesserEqual(tc.b) {
  349. t.Errorf("%+v <= %+v", tc.a, tc.b)
  350. }
  351. }
  352. }
  353. }