sequence_test.go 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  1. package bitseq
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "math/rand"
  6. "testing"
  7. "time"
  8. "github.com/docker/libkv/store"
  9. "github.com/docker/libkv/store/boltdb"
  10. "github.com/docker/libnetwork/datastore"
  11. _ "github.com/docker/libnetwork/testutils"
  12. )
  13. const (
  14. defaultPrefix = "/tmp/libnetwork/test/bitseq"
  15. )
  16. func init() {
  17. boltdb.Register()
  18. }
  19. func randomLocalStore() (datastore.DataStore, error) {
  20. tmp, err := ioutil.TempFile("", "libnetwork-")
  21. if err != nil {
  22. return nil, fmt.Errorf("Error creating temp file: %v", err)
  23. }
  24. if err := tmp.Close(); err != nil {
  25. return nil, fmt.Errorf("Error closing temp file: %v", err)
  26. }
  27. return datastore.NewDataStore(datastore.LocalScope, &datastore.ScopeCfg{
  28. Client: datastore.ScopeClientCfg{
  29. Provider: "boltdb",
  30. Address: defaultPrefix + tmp.Name(),
  31. Config: &store.Config{
  32. Bucket: "libnetwork",
  33. ConnectionTimeout: 3 * time.Second,
  34. },
  35. },
  36. })
  37. }
  38. func TestSequenceGetAvailableBit(t *testing.T) {
  39. input := []struct {
  40. head *sequence
  41. from uint64
  42. bytePos uint64
  43. bitPos uint64
  44. }{
  45. {&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
  46. {&sequence{block: 0x0, count: 1}, 0, 0, 0},
  47. {&sequence{block: 0x0, count: 100}, 0, 0, 0},
  48. {&sequence{block: 0x80000000, count: 0}, 0, invalidPos, invalidPos},
  49. {&sequence{block: 0x80000000, count: 1}, 0, 0, 1},
  50. {&sequence{block: 0x80000000, count: 100}, 0, 0, 1},
  51. {&sequence{block: 0xFF000000, count: 0}, 0, invalidPos, invalidPos},
  52. {&sequence{block: 0xFF000000, count: 1}, 0, 1, 0},
  53. {&sequence{block: 0xFF000000, count: 100}, 0, 1, 0},
  54. {&sequence{block: 0xFF800000, count: 0}, 0, invalidPos, invalidPos},
  55. {&sequence{block: 0xFF800000, count: 1}, 0, 1, 1},
  56. {&sequence{block: 0xFF800000, count: 100}, 0, 1, 1},
  57. {&sequence{block: 0xFFC0FF00, count: 0}, 0, invalidPos, invalidPos},
  58. {&sequence{block: 0xFFC0FF00, count: 1}, 0, 1, 2},
  59. {&sequence{block: 0xFFC0FF00, count: 100}, 0, 1, 2},
  60. {&sequence{block: 0xFFE0FF00, count: 0}, 0, invalidPos, invalidPos},
  61. {&sequence{block: 0xFFE0FF00, count: 1}, 0, 1, 3},
  62. {&sequence{block: 0xFFE0FF00, count: 100}, 0, 1, 3},
  63. {&sequence{block: 0xFFFEFF00, count: 0}, 0, invalidPos, invalidPos},
  64. {&sequence{block: 0xFFFEFF00, count: 1}, 0, 1, 7},
  65. {&sequence{block: 0xFFFEFF00, count: 100}, 0, 1, 7},
  66. {&sequence{block: 0xFFFFC0FF, count: 0}, 0, invalidPos, invalidPos},
  67. {&sequence{block: 0xFFFFC0FF, count: 1}, 0, 2, 2},
  68. {&sequence{block: 0xFFFFC0FF, count: 100}, 0, 2, 2},
  69. {&sequence{block: 0xFFFFFF00, count: 0}, 0, invalidPos, invalidPos},
  70. {&sequence{block: 0xFFFFFF00, count: 1}, 0, 3, 0},
  71. {&sequence{block: 0xFFFFFF00, count: 100}, 0, 3, 0},
  72. {&sequence{block: 0xFFFFFFFE, count: 0}, 0, invalidPos, invalidPos},
  73. {&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7},
  74. {&sequence{block: 0xFFFFFFFE, count: 100}, 0, 3, 7},
  75. {&sequence{block: 0xFFFFFFFF, count: 0}, 0, invalidPos, invalidPos},
  76. {&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos},
  77. {&sequence{block: 0xFFFFFFFF, count: 100}, 0, invalidPos, invalidPos},
  78. // now test with offset
  79. {&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
  80. {&sequence{block: 0x0, count: 0}, 31, invalidPos, invalidPos},
  81. {&sequence{block: 0x0, count: 0}, 32, invalidPos, invalidPos},
  82. {&sequence{block: 0x0, count: 1}, 0, 0, 0},
  83. {&sequence{block: 0x0, count: 1}, 1, 0, 1},
  84. {&sequence{block: 0x0, count: 1}, 31, 3, 7},
  85. {&sequence{block: 0xF0FF0000, count: 1}, 0, 0, 4},
  86. {&sequence{block: 0xF0FF0000, count: 1}, 8, 2, 0},
  87. {&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos},
  88. {&sequence{block: 0xFFFFFFFF, count: 1}, 16, invalidPos, invalidPos},
  89. {&sequence{block: 0xFFFFFFFF, count: 1}, 31, invalidPos, invalidPos},
  90. {&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7},
  91. {&sequence{block: 0xFFFFFFFF, count: 2}, 0, invalidPos, invalidPos},
  92. {&sequence{block: 0xFFFFFFFF, count: 2}, 32, invalidPos, invalidPos},
  93. }
  94. for n, i := range input {
  95. b, bb, err := i.head.getAvailableBit(i.from)
  96. if b != i.bytePos || bb != i.bitPos {
  97. t.Fatalf("Error in sequence.getAvailableBit(%d) (%d).\nExp: (%d, %d)\nGot: (%d, %d), err: %v", i.from, n, i.bytePos, i.bitPos, b, bb, err)
  98. }
  99. }
  100. }
  101. func TestSequenceEqual(t *testing.T) {
  102. input := []struct {
  103. first *sequence
  104. second *sequence
  105. areEqual bool
  106. }{
  107. {&sequence{block: 0x0, count: 8, next: nil}, &sequence{block: 0x0, count: 8}, true},
  108. {&sequence{block: 0x0, count: 0, next: nil}, &sequence{block: 0x0, count: 0}, true},
  109. {&sequence{block: 0x0, count: 2, next: nil}, &sequence{block: 0x0, count: 1, next: &sequence{block: 0x0, count: 1}}, false},
  110. {&sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}, &sequence{block: 0x0, count: 2}, false},
  111. {&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 8}, true},
  112. {&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 9}, false},
  113. {&sequence{block: 0x12345678, count: 1, next: &sequence{block: 0XFFFFFFFF, count: 1}}, &sequence{block: 0x12345678, count: 1}, false},
  114. {&sequence{block: 0x12345678, count: 1}, &sequence{block: 0x12345678, count: 1, next: &sequence{block: 0XFFFFFFFF, count: 1}}, false},
  115. }
  116. for n, i := range input {
  117. if i.areEqual != i.first.equal(i.second) {
  118. t.Fatalf("Error in sequence.equal() (%d).\nExp: %t\nGot: %t,", n, i.areEqual, !i.areEqual)
  119. }
  120. }
  121. }
  122. func TestSequenceCopy(t *testing.T) {
  123. s := getTestSequence()
  124. n := s.getCopy()
  125. if !s.equal(n) {
  126. t.Fatalf("copy of s failed")
  127. }
  128. if n == s {
  129. t.Fatalf("not true copy of s")
  130. }
  131. }
  132. func TestGetFirstAvailable(t *testing.T) {
  133. input := []struct {
  134. mask *sequence
  135. bytePos uint64
  136. bitPos uint64
  137. }{
  138. {&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos},
  139. {&sequence{block: 0x0, count: 8}, 0, 0},
  140. {&sequence{block: 0x80000000, count: 8}, 0, 1},
  141. {&sequence{block: 0xC0000000, count: 8}, 0, 2},
  142. {&sequence{block: 0xE0000000, count: 8}, 0, 3},
  143. {&sequence{block: 0xF0000000, count: 8}, 0, 4},
  144. {&sequence{block: 0xF8000000, count: 8}, 0, 5},
  145. {&sequence{block: 0xFC000000, count: 8}, 0, 6},
  146. {&sequence{block: 0xFE000000, count: 8}, 0, 7},
  147. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 0},
  148. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1},
  149. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2},
  150. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3},
  151. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4},
  152. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5},
  153. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6},
  154. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7},
  155. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0},
  156. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1},
  157. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2},
  158. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3},
  159. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4},
  160. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5},
  161. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6},
  162. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7},
  163. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 7, 7},
  164. {&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0},
  165. }
  166. for n, i := range input {
  167. bytePos, bitPos, _ := getFirstAvailable(i.mask, 0)
  168. if bytePos != i.bytePos || bitPos != i.bitPos {
  169. t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos)
  170. }
  171. }
  172. }
  173. func TestFindSequence(t *testing.T) {
  174. input := []struct {
  175. head *sequence
  176. bytePos uint64
  177. precBlocks uint64
  178. inBlockBytePos uint64
  179. }{
  180. {&sequence{block: 0xffffffff, count: 0}, 0, 0, invalidPos},
  181. {&sequence{block: 0xffffffff, count: 0}, 31, 0, invalidPos},
  182. {&sequence{block: 0xffffffff, count: 0}, 100, 0, invalidPos},
  183. {&sequence{block: 0x0, count: 1}, 0, 0, 0},
  184. {&sequence{block: 0x0, count: 1}, 1, 0, 1},
  185. {&sequence{block: 0x0, count: 1}, 31, 0, invalidPos},
  186. {&sequence{block: 0x0, count: 1}, 60, 0, invalidPos},
  187. {&sequence{block: 0xffffffff, count: 10}, 0, 0, 0},
  188. {&sequence{block: 0xffffffff, count: 10}, 3, 0, 3},
  189. {&sequence{block: 0xffffffff, count: 10}, 4, 1, 0},
  190. {&sequence{block: 0xffffffff, count: 10}, 7, 1, 3},
  191. {&sequence{block: 0xffffffff, count: 10}, 8, 2, 0},
  192. {&sequence{block: 0xffffffff, count: 10}, 39, 9, 3},
  193. {&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 79, 9, 3},
  194. {&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 80, 0, invalidPos},
  195. }
  196. for n, i := range input {
  197. _, _, precBlocks, inBlockBytePos := findSequence(i.head, i.bytePos)
  198. if precBlocks != i.precBlocks || inBlockBytePos != i.inBlockBytePos {
  199. t.Fatalf("Error in (%d) findSequence(). Expected (%d, %d). Got (%d, %d)", n, i.precBlocks, i.inBlockBytePos, precBlocks, inBlockBytePos)
  200. }
  201. }
  202. }
  203. func TestCheckIfAvailable(t *testing.T) {
  204. input := []struct {
  205. head *sequence
  206. ordinal uint64
  207. bytePos uint64
  208. bitPos uint64
  209. }{
  210. {&sequence{block: 0xffffffff, count: 0}, 0, invalidPos, invalidPos},
  211. {&sequence{block: 0xffffffff, count: 0}, 31, invalidPos, invalidPos},
  212. {&sequence{block: 0xffffffff, count: 0}, 100, invalidPos, invalidPos},
  213. {&sequence{block: 0x0, count: 1}, 0, 0, 0},
  214. {&sequence{block: 0x0, count: 1}, 1, 0, 1},
  215. {&sequence{block: 0x0, count: 1}, 31, 3, 7},
  216. {&sequence{block: 0x0, count: 1}, 60, invalidPos, invalidPos},
  217. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 31, invalidPos, invalidPos},
  218. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 32, invalidPos, invalidPos},
  219. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 33, 4, 1},
  220. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 33, invalidPos, invalidPos},
  221. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 34, 4, 2},
  222. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 55, 6, 7},
  223. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 56, invalidPos, invalidPos},
  224. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 63, invalidPos, invalidPos},
  225. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 64, 8, 0},
  226. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 95, 11, 7},
  227. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 96, invalidPos, invalidPos},
  228. }
  229. for n, i := range input {
  230. bytePos, bitPos, err := checkIfAvailable(i.head, i.ordinal)
  231. if bytePos != i.bytePos || bitPos != i.bitPos {
  232. t.Fatalf("Error in (%d) checkIfAvailable(ord:%d). Expected (%d, %d). Got (%d, %d). err: %v", n, i.ordinal, i.bytePos, i.bitPos, bytePos, bitPos, err)
  233. }
  234. }
  235. }
  236. func TestMergeSequences(t *testing.T) {
  237. input := []struct {
  238. original *sequence
  239. merged *sequence
  240. }{
  241. {&sequence{block: 0xFE000000, count: 8, next: &sequence{block: 0xFE000000, count: 2}}, &sequence{block: 0xFE000000, count: 10}},
  242. {&sequence{block: 0xFFFFFFFF, count: 8, next: &sequence{block: 0xFFFFFFFF, count: 1}}, &sequence{block: 0xFFFFFFFF, count: 9}},
  243. {&sequence{block: 0xFFFFFFFF, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 8}}, &sequence{block: 0xFFFFFFFF, count: 9}},
  244. {&sequence{block: 0xFFFFFFF0, count: 8, next: &sequence{block: 0xFFFFFFF0, count: 1}}, &sequence{block: 0xFFFFFFF0, count: 9}},
  245. {&sequence{block: 0xFFFFFFF0, count: 1, next: &sequence{block: 0xFFFFFFF0, count: 8}}, &sequence{block: 0xFFFFFFF0, count: 9}},
  246. {&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5}}}, &sequence{block: 0xFE, count: 14}},
  247. {&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5, next: &sequence{block: 0xFF, count: 1}}}},
  248. &sequence{block: 0xFE, count: 14, next: &sequence{block: 0xFF, count: 1}}},
  249. // No merge
  250. {&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}},
  251. &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}}},
  252. // No merge from head: // Merge function tries to merge from passed head. If it can't merge with next, it does not reattempt with next as head
  253. {&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 1, next: &sequence{block: 0xFF, count: 5}}},
  254. &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 6}}},
  255. }
  256. for n, i := range input {
  257. mergeSequences(i.original)
  258. for !i.merged.equal(i.original) {
  259. t.Fatalf("Error in (%d) mergeSequences().\nExp: %s\nGot: %s,", n, i.merged.toString(), i.original.toString())
  260. }
  261. }
  262. }
  263. func TestPushReservation(t *testing.T) {
  264. input := []struct {
  265. mask *sequence
  266. bytePos uint64
  267. bitPos uint64
  268. newMask *sequence
  269. }{
  270. // Create first sequence and fill in 8 addresses starting from address 0
  271. {&sequence{block: 0x0, count: 8, next: nil}, 0, 0, &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}},
  272. {&sequence{block: 0x80000000, count: 8}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x80000000, count: 7, next: nil}}},
  273. {&sequence{block: 0xC0000000, count: 8}, 0, 2, &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xC0000000, count: 7, next: nil}}},
  274. {&sequence{block: 0xE0000000, count: 8}, 0, 3, &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xE0000000, count: 7, next: nil}}},
  275. {&sequence{block: 0xF0000000, count: 8}, 0, 4, &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xF0000000, count: 7, next: nil}}},
  276. {&sequence{block: 0xF8000000, count: 8}, 0, 5, &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xF8000000, count: 7, next: nil}}},
  277. {&sequence{block: 0xFC000000, count: 8}, 0, 6, &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xFC000000, count: 7, next: nil}}},
  278. {&sequence{block: 0xFE000000, count: 8}, 0, 7, &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xFE000000, count: 7, next: nil}}},
  279. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7}}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}},
  280. // Create second sequence and fill in 8 addresses starting from address 32
  281. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6, next: nil}}}, 4, 0,
  282. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  283. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1,
  284. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  285. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2,
  286. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  287. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3,
  288. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  289. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4,
  290. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  291. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5,
  292. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  293. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6,
  294. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  295. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7,
  296. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  297. // fill in 8 addresses starting from address 40
  298. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0,
  299. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  300. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1,
  301. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  302. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2,
  303. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  304. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3,
  305. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  306. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4,
  307. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  308. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5,
  309. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  310. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6,
  311. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  312. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7,
  313. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFF0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
  314. // Insert new sequence
  315. {&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0,
  316. &sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}},
  317. {&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}, 8, 1,
  318. &sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 5}}}},
  319. // Merge affected with next
  320. {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 2, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
  321. &sequence{block: 0xffffffff, count: 8, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}},
  322. {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffc, count: 1, next: &sequence{block: 0xfffffffe, count: 6}}}, 7, 6,
  323. &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 7}}},
  324. // Merge affected with next and next.next
  325. {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
  326. &sequence{block: 0xffffffff, count: 9}},
  327. {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1}}, 31, 7,
  328. &sequence{block: 0xffffffff, count: 8}},
  329. // Merge affected with previous and next
  330. {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
  331. &sequence{block: 0xffffffff, count: 9}},
  332. // Redundant push: No change
  333. {&sequence{block: 0xffff0000, count: 1}, 0, 0, &sequence{block: 0xffff0000, count: 1}},
  334. {&sequence{block: 0xffff0000, count: 7}, 25, 7, &sequence{block: 0xffff0000, count: 7}},
  335. {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 7, 7,
  336. &sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}},
  337. // Set last bit
  338. {&sequence{block: 0x0, count: 8}, 31, 7, &sequence{block: 0x0, count: 7, next: &sequence{block: 0x1, count: 1}}},
  339. // Set bit in a middle sequence in the first block, first bit
  340. {&sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0,
  341. &sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5,
  342. next: &sequence{block: 0x1, count: 1}}}}},
  343. // Set bit in a middle sequence in the first block, first bit (merge involved)
  344. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0,
  345. &sequence{block: 0x80000000, count: 2, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1}}}},
  346. // Set bit in a middle sequence in the first block, last bit
  347. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 31,
  348. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x1, count: 1, next: &sequence{block: 0x0, count: 5,
  349. next: &sequence{block: 0x1, count: 1}}}}},
  350. // Set bit in a middle sequence in the first block, middle bit
  351. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 16,
  352. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x8000, count: 1, next: &sequence{block: 0x0, count: 5,
  353. next: &sequence{block: 0x1, count: 1}}}}},
  354. // Set bit in a middle sequence in a middle block, first bit
  355. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 0,
  356. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x80000000, count: 1,
  357. next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
  358. // Set bit in a middle sequence in a middle block, last bit
  359. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 31,
  360. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x1, count: 1,
  361. next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
  362. // Set bit in a middle sequence in a middle block, middle bit
  363. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 15,
  364. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x10000, count: 1,
  365. next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
  366. // Set bit in a middle sequence in the last block, first bit
  367. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 0,
  368. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x80000000, count: 1,
  369. next: &sequence{block: 0x1, count: 1}}}}},
  370. // Set bit in a middle sequence in the last block, last bit
  371. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x4, count: 1}}}, 24, 31,
  372. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1,
  373. next: &sequence{block: 0x4, count: 1}}}}},
  374. // Set bit in a middle sequence in the last block, last bit (merge involved)
  375. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 31,
  376. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 2}}}},
  377. // Set bit in a middle sequence in the last block, middle bit
  378. {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 16,
  379. &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x8000, count: 1,
  380. next: &sequence{block: 0x1, count: 1}}}}},
  381. }
  382. for n, i := range input {
  383. mask := pushReservation(i.bytePos, i.bitPos, i.mask, false)
  384. if !mask.equal(i.newMask) {
  385. t.Fatalf("Error in (%d) pushReservation():\n%s + (%d,%d):\nExp: %s\nGot: %s,",
  386. n, i.mask.toString(), i.bytePos, i.bitPos, i.newMask.toString(), mask.toString())
  387. }
  388. }
  389. }
  390. func TestSerializeDeserialize(t *testing.T) {
  391. s := getTestSequence()
  392. data, err := s.toByteArray()
  393. if err != nil {
  394. t.Fatal(err)
  395. }
  396. r := &sequence{}
  397. err = r.fromByteArray(data)
  398. if err != nil {
  399. t.Fatal(err)
  400. }
  401. if !s.equal(r) {
  402. t.Fatalf("Sequences are different: \n%v\n%v", s, r)
  403. }
  404. }
  405. func getTestSequence() *sequence {
  406. // Returns a custom sequence of 1024 * 32 bits
  407. return &sequence{
  408. block: 0XFFFFFFFF,
  409. count: 100,
  410. next: &sequence{
  411. block: 0xFFFFFFFE,
  412. count: 1,
  413. next: &sequence{
  414. block: 0xFF000000,
  415. count: 10,
  416. next: &sequence{
  417. block: 0XFFFFFFFF,
  418. count: 50,
  419. next: &sequence{
  420. block: 0XFFFFFFFC,
  421. count: 1,
  422. next: &sequence{
  423. block: 0xFF800000,
  424. count: 1,
  425. next: &sequence{
  426. block: 0XFFFFFFFF,
  427. count: 87,
  428. next: &sequence{
  429. block: 0x0,
  430. count: 150,
  431. next: &sequence{
  432. block: 0XFFFFFFFF,
  433. count: 200,
  434. next: &sequence{
  435. block: 0x0000FFFF,
  436. count: 1,
  437. next: &sequence{
  438. block: 0x0,
  439. count: 399,
  440. next: &sequence{
  441. block: 0XFFFFFFFF,
  442. count: 23,
  443. next: &sequence{
  444. block: 0x1,
  445. count: 1,
  446. },
  447. },
  448. },
  449. },
  450. },
  451. },
  452. },
  453. },
  454. },
  455. },
  456. },
  457. },
  458. }
  459. }
  460. func TestSet(t *testing.T) {
  461. hnd, err := NewHandle("", nil, "", 1024*32)
  462. if err != nil {
  463. t.Fatal(err)
  464. }
  465. hnd.head = getTestSequence()
  466. firstAv := uint64(32*100 + 31)
  467. last := uint64(1024*32 - 1)
  468. if hnd.IsSet(100000) {
  469. t.Fatal("IsSet() returned wrong result")
  470. }
  471. if !hnd.IsSet(0) {
  472. t.Fatal("IsSet() returned wrong result")
  473. }
  474. if hnd.IsSet(firstAv) {
  475. t.Fatal("IsSet() returned wrong result")
  476. }
  477. if !hnd.IsSet(last) {
  478. t.Fatal("IsSet() returned wrong result")
  479. }
  480. if err := hnd.Set(0); err == nil {
  481. t.Fatalf("Expected failure, but succeeded")
  482. }
  483. os, err := hnd.SetAny()
  484. if err != nil {
  485. t.Fatalf("Unexpected failure: %v", err)
  486. }
  487. if os != firstAv {
  488. t.Fatalf("SetAny returned unexpected ordinal. Expected %d. Got %d.", firstAv, os)
  489. }
  490. if !hnd.IsSet(firstAv) {
  491. t.Fatal("IsSet() returned wrong result")
  492. }
  493. if err := hnd.Unset(firstAv); err != nil {
  494. t.Fatalf("Unexpected failure: %v", err)
  495. }
  496. if hnd.IsSet(firstAv) {
  497. t.Fatal("IsSet() returned wrong result")
  498. }
  499. if err := hnd.Set(firstAv); err != nil {
  500. t.Fatalf("Unexpected failure: %v", err)
  501. }
  502. if err := hnd.Set(last); err == nil {
  503. t.Fatalf("Expected failure, but succeeded")
  504. }
  505. }
  506. func TestSetUnset(t *testing.T) {
  507. numBits := uint64(32 * blockLen)
  508. hnd, err := NewHandle("", nil, "", numBits)
  509. if err != nil {
  510. t.Fatal(err)
  511. }
  512. if err := hnd.Set(uint64(32 * blockLen)); err == nil {
  513. t.Fatalf("Expected failure, but succeeded")
  514. }
  515. if err := hnd.Unset(uint64(32 * blockLen)); err == nil {
  516. t.Fatalf("Expected failure, but succeeded")
  517. }
  518. // set and unset all one by one
  519. for hnd.Unselected() > 0 {
  520. if _, err := hnd.SetAny(); err != nil {
  521. t.Fatal(err)
  522. }
  523. }
  524. if _, err := hnd.SetAny(); err != ErrNoBitAvailable {
  525. t.Fatalf("Expected error. Got success")
  526. }
  527. if _, err := hnd.SetAnyInRange(10, 20); err != ErrNoBitAvailable {
  528. t.Fatalf("Expected error. Got success")
  529. }
  530. if err := hnd.Set(50); err != ErrBitAllocated {
  531. t.Fatalf("Expected error. Got %v: %s", err, hnd)
  532. }
  533. i := uint64(0)
  534. for hnd.Unselected() < numBits {
  535. if err := hnd.Unset(i); err != nil {
  536. t.Fatal(err)
  537. }
  538. i++
  539. }
  540. }
  541. func TestSetInRange(t *testing.T) {
  542. numBits := uint64(1024 * blockLen)
  543. hnd, err := NewHandle("", nil, "", numBits)
  544. if err != nil {
  545. t.Fatal(err)
  546. }
  547. hnd.head = getTestSequence()
  548. firstAv := uint64(100*blockLen + blockLen - 1)
  549. if o, err := hnd.SetAnyInRange(4, 3); err == nil {
  550. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  551. }
  552. if o, err := hnd.SetAnyInRange(5, 5); err == nil {
  553. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  554. }
  555. if o, err := hnd.SetAnyInRange(0, numBits); err == nil {
  556. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  557. }
  558. o, err := hnd.SetAnyInRange(100*uint64(blockLen), 101*uint64(blockLen))
  559. if err != nil {
  560. t.Fatalf("Unexpected failure: (%d, %v)", o, err)
  561. }
  562. if o != firstAv {
  563. t.Fatalf("Unexpected ordinal: %d", o)
  564. }
  565. if o, err := hnd.SetAnyInRange(0, uint64(blockLen)); err == nil {
  566. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  567. }
  568. if o, err := hnd.SetAnyInRange(0, firstAv-1); err == nil {
  569. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  570. }
  571. if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen)); err == nil {
  572. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  573. }
  574. o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
  575. if err != nil {
  576. t.Fatal(err)
  577. }
  578. if o != 161*uint64(blockLen)+30 {
  579. t.Fatalf("Unexpected ordinal: %d", o)
  580. }
  581. o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
  582. if err != nil {
  583. t.Fatal(err)
  584. }
  585. if o != 161*uint64(blockLen)+31 {
  586. t.Fatalf("Unexpected ordinal: %d", o)
  587. }
  588. o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
  589. if err == nil {
  590. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  591. }
  592. if _, err := hnd.SetAnyInRange(0, numBits-1); err != nil {
  593. t.Fatalf("Unexpected failure: %v", err)
  594. }
  595. // create a non multiple of 32 mask
  596. hnd, err = NewHandle("", nil, "", 30)
  597. if err != nil {
  598. t.Fatal(err)
  599. }
  600. // set all bit in the first range
  601. for hnd.Unselected() > 22 {
  602. if o, err := hnd.SetAnyInRange(0, 7); err != nil {
  603. t.Fatalf("Unexpected failure: (%d, %v)", o, err)
  604. }
  605. }
  606. // try one more set, which should fail
  607. o, err = hnd.SetAnyInRange(0, 7)
  608. if err == nil {
  609. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  610. }
  611. if err != ErrNoBitAvailable {
  612. t.Fatalf("Unexpected error: %v", err)
  613. }
  614. // set all bit in a second range
  615. for hnd.Unselected() > 14 {
  616. if o, err := hnd.SetAnyInRange(8, 15); err != nil {
  617. t.Fatalf("Unexpected failure: (%d, %v)", o, err)
  618. }
  619. }
  620. // try one more set, which should fail
  621. o, err = hnd.SetAnyInRange(0, 15)
  622. if err == nil {
  623. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  624. }
  625. if err != ErrNoBitAvailable {
  626. t.Fatalf("Unexpected error: %v", err)
  627. }
  628. // set all bit in a range which includes the last bit
  629. for hnd.Unselected() > 12 {
  630. if o, err := hnd.SetAnyInRange(28, 29); err != nil {
  631. t.Fatalf("Unexpected failure: (%d, %v)", o, err)
  632. }
  633. }
  634. o, err = hnd.SetAnyInRange(28, 29)
  635. if err == nil {
  636. t.Fatalf("Expected failure. Got success with ordinal:%d", o)
  637. }
  638. if err != ErrNoBitAvailable {
  639. t.Fatalf("Unexpected error: %v", err)
  640. }
  641. }
  642. // This one tests an allocation pattern which unveiled an issue in pushReservation
  643. // Specifically a failure in detecting when we are in the (B) case (the bit to set
  644. // belongs to the last block of the current sequence). Because of a bug, code
  645. // was assuming the bit belonged to a block in the middle of the current sequence.
  646. // Which in turn caused an incorrect allocation when requesting a bit which is not
  647. // in the first or last sequence block.
  648. func TestSetAnyInRange(t *testing.T) {
  649. numBits := uint64(8 * blockLen)
  650. hnd, err := NewHandle("", nil, "", numBits)
  651. if err != nil {
  652. t.Fatal(err)
  653. }
  654. if err := hnd.Set(0); err != nil {
  655. t.Fatal(err)
  656. }
  657. if err := hnd.Set(255); err != nil {
  658. t.Fatal(err)
  659. }
  660. o, err := hnd.SetAnyInRange(128, 255)
  661. if err != nil {
  662. t.Fatal(err)
  663. }
  664. if o != 128 {
  665. t.Fatalf("Unexpected ordinal: %d", o)
  666. }
  667. o, err = hnd.SetAnyInRange(128, 255)
  668. if err != nil {
  669. t.Fatal(err)
  670. }
  671. if o != 129 {
  672. t.Fatalf("Unexpected ordinal: %d", o)
  673. }
  674. o, err = hnd.SetAnyInRange(246, 255)
  675. if err != nil {
  676. t.Fatal(err)
  677. }
  678. if o != 246 {
  679. t.Fatalf("Unexpected ordinal: %d", o)
  680. }
  681. o, err = hnd.SetAnyInRange(246, 255)
  682. if err != nil {
  683. t.Fatal(err)
  684. }
  685. if o != 247 {
  686. t.Fatalf("Unexpected ordinal: %d", o)
  687. }
  688. }
  689. func TestMethods(t *testing.T) {
  690. numBits := uint64(256 * blockLen)
  691. hnd, err := NewHandle("path/to/data", nil, "sequence1", uint64(numBits))
  692. if err != nil {
  693. t.Fatal(err)
  694. }
  695. if hnd.Bits() != numBits {
  696. t.Fatalf("Unexpected bit number: %d", hnd.Bits())
  697. }
  698. if hnd.Unselected() != numBits {
  699. t.Fatalf("Unexpected bit number: %d", hnd.Unselected())
  700. }
  701. exp := "(0x0, 256)->end"
  702. if hnd.head.toString() != exp {
  703. t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
  704. }
  705. for i := 0; i < 192; i++ {
  706. _, err := hnd.SetAny()
  707. if err != nil {
  708. t.Fatal(err)
  709. }
  710. }
  711. exp = "(0xffffffff, 6)->(0x0, 250)->end"
  712. if hnd.head.toString() != exp {
  713. t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
  714. }
  715. }
  716. func TestRandomAllocateDeallocate(t *testing.T) {
  717. ds, err := randomLocalStore()
  718. if err != nil {
  719. t.Fatal(err)
  720. }
  721. numBits := int(16 * blockLen)
  722. hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
  723. if err != nil {
  724. t.Fatal(err)
  725. }
  726. seed := time.Now().Unix()
  727. rand.Seed(seed)
  728. // Allocate all bits using a random pattern
  729. pattern := rand.Perm(numBits)
  730. for _, bit := range pattern {
  731. err := hnd.Set(uint64(bit))
  732. if err != nil {
  733. t.Fatalf("Unexpected failure on allocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
  734. }
  735. }
  736. if hnd.Unselected() != 0 {
  737. t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
  738. }
  739. if hnd.head.toString() != "(0xffffffff, 16)->end" {
  740. t.Fatalf("Unexpected db: %s", hnd.head.toString())
  741. }
  742. // Deallocate all bits using a random pattern
  743. pattern = rand.Perm(numBits)
  744. for _, bit := range pattern {
  745. err := hnd.Unset(uint64(bit))
  746. if err != nil {
  747. t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
  748. }
  749. }
  750. if hnd.Unselected() != uint64(numBits) {
  751. t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
  752. }
  753. if hnd.head.toString() != "(0x0, 16)->end" {
  754. t.Fatalf("Unexpected db: %s", hnd.head.toString())
  755. }
  756. err = hnd.Destroy()
  757. if err != nil {
  758. t.Fatal(err)
  759. }
  760. }
  761. func TestAllocateRandomDeallocate(t *testing.T) {
  762. ds, err := randomLocalStore()
  763. if err != nil {
  764. t.Fatal(err)
  765. }
  766. numBlocks := uint32(8)
  767. numBits := int(numBlocks * blockLen)
  768. hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
  769. if err != nil {
  770. t.Fatal(err)
  771. }
  772. expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}}
  773. // Allocate first half of the bits
  774. for i := 0; i < numBits/2; i++ {
  775. _, err := hnd.SetAny()
  776. if err != nil {
  777. t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
  778. }
  779. }
  780. if hnd.Unselected() != uint64(numBits/2) {
  781. t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
  782. }
  783. if !hnd.head.equal(expected) {
  784. t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
  785. }
  786. seed := time.Now().Unix()
  787. rand.Seed(seed)
  788. // Deallocate half of the allocated bits following a random pattern
  789. pattern := rand.Perm(numBits / 2)
  790. for i := 0; i < numBits/4; i++ {
  791. bit := pattern[i]
  792. err := hnd.Unset(uint64(bit))
  793. if err != nil {
  794. t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
  795. }
  796. }
  797. if hnd.Unselected() != uint64(3*numBits/4) {
  798. t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
  799. }
  800. // Request a quarter of bits
  801. for i := 0; i < numBits/4; i++ {
  802. _, err := hnd.SetAny()
  803. if err != nil {
  804. t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
  805. }
  806. }
  807. if hnd.Unselected() != uint64(numBits/2) {
  808. t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd)
  809. }
  810. if !hnd.head.equal(expected) {
  811. t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
  812. }
  813. err = hnd.Destroy()
  814. if err != nil {
  815. t.Fatal(err)
  816. }
  817. }
  818. func TestRetrieveFromStore(t *testing.T) {
  819. ds, err := randomLocalStore()
  820. if err != nil {
  821. t.Fatal(err)
  822. }
  823. numBits := int(8 * blockLen)
  824. hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
  825. if err != nil {
  826. t.Fatal(err)
  827. }
  828. // Allocate first half of the bits
  829. for i := 0; i < numBits/2; i++ {
  830. _, err := hnd.SetAny()
  831. if err != nil {
  832. t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
  833. }
  834. }
  835. hnd0 := hnd.String()
  836. // Retrieve same handle
  837. hnd, err = NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
  838. if err != nil {
  839. t.Fatal(err)
  840. }
  841. hnd1 := hnd.String()
  842. if hnd1 != hnd0 {
  843. t.Fatalf("%v\n%v", hnd0, hnd1)
  844. }
  845. err = hnd.Destroy()
  846. if err != nil {
  847. t.Fatal(err)
  848. }
  849. }
  850. func TestIsCorrupted(t *testing.T) {
  851. ds, err := randomLocalStore()
  852. if err != nil {
  853. t.Fatal(err)
  854. }
  855. // Negative test
  856. hnd, err := NewHandle("bitseq-test/data/", ds, "test_corrupted", 1024)
  857. if err != nil {
  858. t.Fatal(err)
  859. }
  860. if hnd.runConsistencyCheck() {
  861. t.Fatalf("Unexpected corrupted for %s", hnd)
  862. }
  863. if err := hnd.CheckConsistency(); err != nil {
  864. t.Fatal(err)
  865. }
  866. hnd.Set(0)
  867. if hnd.runConsistencyCheck() {
  868. t.Fatalf("Unexpected corrupted for %s", hnd)
  869. }
  870. hnd.Set(1023)
  871. if hnd.runConsistencyCheck() {
  872. t.Fatalf("Unexpected corrupted for %s", hnd)
  873. }
  874. if err := hnd.CheckConsistency(); err != nil {
  875. t.Fatal(err)
  876. }
  877. // Try real corrupted ipam handles found in the local store files reported by three docker users,
  878. // plus a generic ipam handle from docker 1.9.1. This last will fail as well, because of how the
  879. // last node in the sequence is expressed (This is true for IPAM handle only, because of the broadcast
  880. // address reservation: last bit). This will allow an application using bitseq that runs a consistency
  881. // check to detect and replace the 1.9.0/1 old vulnerable handle with the new one.
  882. input := []*Handle{
  883. {
  884. id: "LocalDefault/172.17.0.0/16",
  885. bits: 65536,
  886. unselected: 65412,
  887. head: &sequence{
  888. block: 0xffffffff,
  889. count: 3,
  890. next: &sequence{
  891. block: 0xffffffbf,
  892. count: 0,
  893. next: &sequence{
  894. block: 0xfe98816e,
  895. count: 1,
  896. next: &sequence{
  897. block: 0xffffffff,
  898. count: 0,
  899. next: &sequence{
  900. block: 0xe3bc0000,
  901. count: 1,
  902. next: &sequence{
  903. block: 0x0,
  904. count: 2042,
  905. next: &sequence{
  906. block: 0x1, count: 1,
  907. next: &sequence{
  908. block: 0x0, count: 0,
  909. },
  910. },
  911. },
  912. },
  913. },
  914. },
  915. },
  916. },
  917. },
  918. {
  919. id: "LocalDefault/172.17.0.0/16",
  920. bits: 65536,
  921. unselected: 65319,
  922. head: &sequence{
  923. block: 0xffffffff,
  924. count: 7,
  925. next: &sequence{
  926. block: 0xffffff7f,
  927. count: 0,
  928. next: &sequence{
  929. block: 0xffffffff,
  930. count: 0,
  931. next: &sequence{
  932. block: 0x2000000,
  933. count: 1,
  934. next: &sequence{
  935. block: 0x0,
  936. count: 2039,
  937. next: &sequence{
  938. block: 0x1,
  939. count: 1,
  940. next: &sequence{
  941. block: 0x0,
  942. count: 0,
  943. },
  944. },
  945. },
  946. },
  947. },
  948. },
  949. },
  950. },
  951. {
  952. id: "LocalDefault/172.17.0.0/16",
  953. bits: 65536,
  954. unselected: 65456,
  955. head: &sequence{
  956. block: 0xffffffff, count: 2,
  957. next: &sequence{
  958. block: 0xfffbffff, count: 0,
  959. next: &sequence{
  960. block: 0xffd07000, count: 1,
  961. next: &sequence{
  962. block: 0x0, count: 333,
  963. next: &sequence{
  964. block: 0x40000000, count: 1,
  965. next: &sequence{
  966. block: 0x0, count: 1710,
  967. next: &sequence{
  968. block: 0x1, count: 1,
  969. next: &sequence{
  970. block: 0x0, count: 0,
  971. },
  972. },
  973. },
  974. },
  975. },
  976. },
  977. },
  978. },
  979. },
  980. }
  981. for idx, hnd := range input {
  982. if !hnd.runConsistencyCheck() {
  983. t.Fatalf("Expected corrupted for (%d): %s", idx, hnd)
  984. }
  985. if hnd.runConsistencyCheck() {
  986. t.Fatalf("Sequence still marked corrupted (%d): %s", idx, hnd)
  987. }
  988. }
  989. }