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