vector_test.go 11 KB

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