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