index_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package storage
  2. import (
  3. "reflect"
  4. "testing"
  5. )
  6. func TestIndexGet(t *testing.T) {
  7. index := newTreeIndex()
  8. index.Put([]byte("foo"), revision{main: 2})
  9. index.Put([]byte("foo"), revision{main: 4})
  10. index.Tombstone([]byte("foo"), revision{main: 6})
  11. tests := []struct {
  12. rev int64
  13. wrev revision
  14. wcreated revision
  15. wver int64
  16. werr error
  17. }{
  18. {0, revision{}, revision{}, 0, ErrRevisionNotFound},
  19. {1, revision{}, revision{}, 0, ErrRevisionNotFound},
  20. {2, revision{main: 2}, revision{main: 2}, 1, nil},
  21. {3, revision{main: 2}, revision{main: 2}, 1, nil},
  22. {4, revision{main: 4}, revision{main: 2}, 2, nil},
  23. {5, revision{main: 4}, revision{main: 2}, 2, nil},
  24. {6, revision{}, revision{}, 0, ErrRevisionNotFound},
  25. }
  26. for i, tt := range tests {
  27. rev, created, ver, err := index.Get([]byte("foo"), tt.rev)
  28. if err != tt.werr {
  29. t.Errorf("#%d: err = %v, want %v", i, err, tt.werr)
  30. }
  31. if rev != tt.wrev {
  32. t.Errorf("#%d: rev = %+v, want %+v", i, rev, tt.wrev)
  33. }
  34. if created != tt.wcreated {
  35. t.Errorf("#%d: created = %+v, want %+v", i, created, tt.wcreated)
  36. }
  37. if ver != tt.wver {
  38. t.Errorf("#%d: ver = %d, want %d", i, ver, tt.wver)
  39. }
  40. }
  41. }
  42. func TestIndexRange(t *testing.T) {
  43. allKeys := [][]byte{[]byte("foo"), []byte("foo1"), []byte("foo2")}
  44. allRevs := []revision{{main: 1}, {main: 2}, {main: 3}}
  45. index := newTreeIndex()
  46. for i := range allKeys {
  47. index.Put(allKeys[i], allRevs[i])
  48. }
  49. atRev := int64(3)
  50. tests := []struct {
  51. key, end []byte
  52. wkeys [][]byte
  53. wrevs []revision
  54. }{
  55. // single key that not found
  56. {
  57. []byte("bar"), nil, nil, nil,
  58. },
  59. // single key that found
  60. {
  61. []byte("foo"), nil, allKeys[:1], allRevs[:1],
  62. },
  63. // range keys, return first member
  64. {
  65. []byte("foo"), []byte("foo1"), allKeys[:1], allRevs[:1],
  66. },
  67. // range keys, return first two members
  68. {
  69. []byte("foo"), []byte("foo2"), allKeys[:2], allRevs[:2],
  70. },
  71. // range keys, return all members
  72. {
  73. []byte("foo"), []byte("fop"), allKeys, allRevs,
  74. },
  75. // range keys, return last two members
  76. {
  77. []byte("foo1"), []byte("fop"), allKeys[1:], allRevs[1:],
  78. },
  79. // range keys, return last member
  80. {
  81. []byte("foo2"), []byte("fop"), allKeys[2:], allRevs[2:],
  82. },
  83. // range keys, return nothing
  84. {
  85. []byte("foo3"), []byte("fop"), nil, nil,
  86. },
  87. }
  88. for i, tt := range tests {
  89. keys, revs := index.Range(tt.key, tt.end, atRev)
  90. if !reflect.DeepEqual(keys, tt.wkeys) {
  91. t.Errorf("#%d: keys = %+v, want %+v", i, keys, tt.wkeys)
  92. }
  93. if !reflect.DeepEqual(revs, tt.wrevs) {
  94. t.Errorf("#%d: revs = %+v, want %+v", i, revs, tt.wrevs)
  95. }
  96. }
  97. }
  98. func TestIndexTombstone(t *testing.T) {
  99. index := newTreeIndex()
  100. index.Put([]byte("foo"), revision{main: 1})
  101. err := index.Tombstone([]byte("foo"), revision{main: 2})
  102. if err != nil {
  103. t.Errorf("tombstone error = %v, want nil", err)
  104. }
  105. _, _, _, err = index.Get([]byte("foo"), 2)
  106. if err != ErrRevisionNotFound {
  107. t.Errorf("get error = %v, want nil", err)
  108. }
  109. err = index.Tombstone([]byte("foo"), revision{main: 3})
  110. if err != ErrRevisionNotFound {
  111. t.Errorf("tombstone error = %v, want %v", err, ErrRevisionNotFound)
  112. }
  113. }
  114. func TestIndexCompact(t *testing.T) {
  115. maxRev := int64(20)
  116. tests := []struct {
  117. key []byte
  118. remove bool
  119. rev revision
  120. created revision
  121. ver int64
  122. }{
  123. {[]byte("foo"), false, revision{main: 1}, revision{main: 1}, 1},
  124. {[]byte("foo1"), false, revision{main: 2}, revision{main: 2}, 1},
  125. {[]byte("foo2"), false, revision{main: 3}, revision{main: 3}, 1},
  126. {[]byte("foo2"), false, revision{main: 4}, revision{main: 3}, 2},
  127. {[]byte("foo"), false, revision{main: 5}, revision{main: 1}, 2},
  128. {[]byte("foo1"), false, revision{main: 6}, revision{main: 2}, 2},
  129. {[]byte("foo1"), true, revision{main: 7}, revision{}, 0},
  130. {[]byte("foo2"), true, revision{main: 8}, revision{}, 0},
  131. {[]byte("foo"), true, revision{main: 9}, revision{}, 0},
  132. {[]byte("foo"), false, revision{10, 0}, revision{10, 0}, 1},
  133. {[]byte("foo1"), false, revision{10, 1}, revision{10, 1}, 1},
  134. }
  135. // Continuous Compact
  136. index := newTreeIndex()
  137. for _, tt := range tests {
  138. if tt.remove {
  139. index.Tombstone(tt.key, tt.rev)
  140. } else {
  141. index.Put(tt.key, tt.rev)
  142. }
  143. }
  144. for i := int64(1); i < maxRev; i++ {
  145. am := index.Compact(i)
  146. windex := newTreeIndex()
  147. for _, tt := range tests {
  148. if _, ok := am[tt.rev]; ok || tt.rev.GreaterThan(revision{main: i}) {
  149. if tt.remove {
  150. windex.Tombstone(tt.key, tt.rev)
  151. } else {
  152. windex.Restore(tt.key, tt.created, tt.rev, tt.ver)
  153. }
  154. }
  155. }
  156. if !index.Equal(windex) {
  157. t.Errorf("#%d: not equal index", i)
  158. }
  159. }
  160. // Once Compact
  161. for i := int64(1); i < maxRev; i++ {
  162. index := newTreeIndex()
  163. for _, tt := range tests {
  164. if tt.remove {
  165. index.Tombstone(tt.key, tt.rev)
  166. } else {
  167. index.Put(tt.key, tt.rev)
  168. }
  169. }
  170. am := index.Compact(i)
  171. windex := newTreeIndex()
  172. for _, tt := range tests {
  173. if _, ok := am[tt.rev]; ok || tt.rev.GreaterThan(revision{main: i}) {
  174. if tt.remove {
  175. windex.Tombstone(tt.key, tt.rev)
  176. } else {
  177. windex.Restore(tt.key, tt.created, tt.rev, tt.ver)
  178. }
  179. }
  180. }
  181. if !index.Equal(windex) {
  182. t.Errorf("#%d: not equal index", i)
  183. }
  184. }
  185. }
  186. func TestIndexRestore(t *testing.T) {
  187. key := []byte("foo")
  188. tests := []struct {
  189. created revision
  190. modified revision
  191. ver int64
  192. }{
  193. {revision{1, 0}, revision{1, 0}, 1},
  194. {revision{1, 0}, revision{1, 1}, 2},
  195. {revision{1, 0}, revision{2, 0}, 3},
  196. }
  197. // Continuous Restore
  198. index := newTreeIndex()
  199. for i, tt := range tests {
  200. index.Restore(key, tt.created, tt.modified, tt.ver)
  201. modified, created, ver, err := index.Get(key, tt.modified.main)
  202. if modified != tt.modified {
  203. t.Errorf("#%d: modified = %v, want %v", i, modified, tt.modified)
  204. }
  205. if created != tt.created {
  206. t.Errorf("#%d: created = %v, want %v", i, created, tt.created)
  207. }
  208. if ver != tt.ver {
  209. t.Errorf("#%d: ver = %d, want %d", i, ver, tt.ver)
  210. }
  211. if err != nil {
  212. t.Errorf("#%d: err = %v, want nil", i, err)
  213. }
  214. }
  215. // Once Restore
  216. for i, tt := range tests {
  217. index := newTreeIndex()
  218. index.Restore(key, tt.created, tt.modified, tt.ver)
  219. modified, created, ver, err := index.Get(key, tt.modified.main)
  220. if modified != tt.modified {
  221. t.Errorf("#%d: modified = %v, want %v", i, modified, tt.modified)
  222. }
  223. if created != tt.created {
  224. t.Errorf("#%d: created = %v, want %v", i, created, tt.created)
  225. }
  226. if ver != tt.ver {
  227. t.Errorf("#%d: ver = %d, want %d", i, ver, tt.ver)
  228. }
  229. if err != nil {
  230. t.Errorf("#%d: err = %v, want nil", i, err)
  231. }
  232. }
  233. }