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